diff options
Diffstat (limited to 'main/src/cgeo/geocaching/connector')
29 files changed, 332 insertions, 133 deletions
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java index 4984273..0583aa1 100644 --- a/main/src/cgeo/geocaching/connector/AbstractConnector.java +++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java @@ -19,6 +19,7 @@ import cgeo.geocaching.location.Geopoint; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import rx.functions.Action1; @@ -129,7 +130,8 @@ public abstract class AbstractConnector implements IConnector { } @Override - public String getGeocodeFromUrl(final String url) { + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { final String urlPrefix = getCacheUrlPrefix(); if (StringUtils.isEmpty(urlPrefix) || StringUtils.startsWith(url, urlPrefix)) { @NonNull final String geocode = url.substring(urlPrefix.length()); @@ -144,7 +146,7 @@ public abstract class AbstractConnector implements IConnector { abstract protected String getCacheUrlPrefix(); @Override - @NonNull + @Nullable public String getLongCacheUrl(final @NonNull Geocache cache) { return getCacheUrl(cache); } @@ -201,7 +203,7 @@ public abstract class AbstractConnector implements IConnector { } @Override - public String getWaypointGpxId(final String prefix, final String geocode) { + public String getWaypointGpxId(final String prefix, @NonNull final String geocode) { // Default: just return the prefix return prefix; } diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java index b78b009..918911a 100644 --- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java +++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java @@ -15,9 +15,11 @@ import cgeo.geocaching.connector.gc.GCConnector; import cgeo.geocaching.connector.gc.MapTokens; import cgeo.geocaching.connector.oc.OCApiConnector.ApiSupport; import cgeo.geocaching.connector.oc.OCApiLiveConnector; +import cgeo.geocaching.connector.oc.OCCZConnector; import cgeo.geocaching.connector.oc.OCConnector; import cgeo.geocaching.connector.ox.OXConnector; import cgeo.geocaching.connector.trackable.GeokretyConnector; +import cgeo.geocaching.connector.trackable.SwaggieConnector; import cgeo.geocaching.connector.trackable.TrackableConnector; import cgeo.geocaching.connector.trackable.TravelBugConnector; import cgeo.geocaching.connector.trackable.UnknownTrackableConnector; @@ -43,7 +45,7 @@ public final class ConnectorFactory { new OCApiLiveConnector("opencaching.de", "www.opencaching.de", "OC", "CC BY-NC-ND, alle Logeinträge © jeweiliger Autor", R.string.oc_de_okapi_consumer_key, R.string.oc_de_okapi_consumer_secret, R.string.pref_connectorOCActive, R.string.pref_ocde_tokenpublic, R.string.pref_ocde_tokensecret, ApiSupport.current), - new OCConnector("OpenCaching.CZ", "www.opencaching.cz", "OZ"), + new OCCZConnector(), new OCApiLiveConnector("opencaching.org.uk", "www.opencaching.org.uk", "OK", "CC BY-NC-SA 2.5", R.string.oc_uk_okapi_consumer_key, R.string.oc_uk_okapi_consumer_secret, R.string.pref_connectorOCUKActive, R.string.pref_ocuk_tokenpublic, R.string.pref_ocuk_tokensecret, ApiSupport.oldapi), @@ -74,8 +76,9 @@ public final class ConnectorFactory { @NonNull private static final Collection<TrackableConnector> TRACKABLE_CONNECTORS = Collections.unmodifiableCollection(Arrays.asList(new TrackableConnector[] { - new GeokretyConnector(), // GK must be first, as it overlaps with the secret codes of travel bugs - TravelBugConnector.getInstance(), + new GeokretyConnector(), + new SwaggieConnector(), + TravelBugConnector.getInstance(), // travel bugs last, as their secret codes overlap with other connectors UNKNOWN_TRACKABLE_CONNECTOR // must be last })); @@ -212,9 +215,12 @@ public final class ConnectorFactory { } @Nullable - public static String getGeocodeFromURL(final String url) { + public static String getGeocodeFromURL(@Nullable final String url) { + if (url == null) { + return null; + } for (final IConnector connector : CONNECTORS) { - final String geocode = connector.getGeocodeFromUrl(url); + @Nullable final String geocode = connector.getGeocodeFromUrl(url); if (StringUtils.isNotBlank(geocode)) { return geocode; } @@ -230,7 +236,6 @@ public final class ConnectorFactory { /** * Get the geocode of a trackable from a URL. * - * @param url * @return {@code null} if the URL cannot be decoded */ @Nullable diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java index 0863723..74b1028 100644 --- a/main/src/cgeo/geocaching/connector/IConnector.java +++ b/main/src/cgeo/geocaching/connector/IConnector.java @@ -6,6 +6,7 @@ import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.location.Geopoint; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import java.util.Collection; import java.util.List; @@ -14,7 +15,6 @@ public interface IConnector { /** * get name for display (currently only used in links) * - * @return */ @NonNull public String getName(); @@ -31,32 +31,26 @@ public interface IConnector { /** * Get the browser URL for the given cache. * - * @param cache - * @return */ - @NonNull + @Nullable public String getCacheUrl(final @NonNull Geocache cache); /** * get long browser URL for the given cache * - * @param cache - * @return */ - @NonNull + @Nullable public String getLongCacheUrl(final @NonNull Geocache cache); /** * enable/disable watchlist controls in cache details * - * @return */ public boolean supportsWatchList(); /** * Add the cache to the watchlist * - * @param cache * @return True - success/False - failure */ public boolean addToWatchlist(@NonNull Geocache cache); @@ -64,7 +58,6 @@ public interface IConnector { /** * Remove the cache from the watchlist * - * @param cache * @return True - success/False - failure */ public boolean removeFromWatchlist(@NonNull Geocache cache); @@ -72,28 +65,24 @@ public interface IConnector { /** * enable/disable favorite points controls in cache details * - * @return */ public boolean supportsFavoritePoints(@NonNull final Geocache cache); /** * enable/disable logging controls in cache details * - * @return */ public boolean supportsLogging(); /** * enable/disable attaching image to log * - * @return */ public boolean supportsLogImages(); /** * Get an ILoggingManager to guide the logging process. * - * @return */ @NonNull public ILoggingManager getLoggingManager(@NonNull final LogCacheActivity activity, @NonNull final Geocache cache); @@ -101,7 +90,6 @@ public interface IConnector { /** * Get host name of the connector server for dynamic loading of data. * - * @return */ @NonNull public String getHost(); @@ -109,8 +97,6 @@ public interface IConnector { /** * Get cache data license text. This is displayed somewhere near the cache details. * - * @param cache - * @return */ @NonNull public String getLicenseText(final @NonNull Geocache cache); @@ -118,8 +104,6 @@ public interface IConnector { /** * return true if this is a ZIP file containing a GPX file * - * @param fileName - * @return */ public boolean isZippedGPXFile(@NonNull final String fileName); @@ -128,17 +112,15 @@ public interface IConnector { * * @param cacheHasReliableLatLon * flag of the cache - * @return */ public boolean isReliableLatLon(boolean cacheHasReliableLatLon); /** * extract a geocode from the given URL, if this connector can handle that URL somehow * - * @param url - * @return */ - public String getGeocodeFromUrl(final String url); + @Nullable + public String getGeocodeFromUrl(@NonNull final String url); /** * enable/disable uploading personal note @@ -150,7 +132,6 @@ public interface IConnector { /** * Uploading personal note to website * - * @param cache * @return success */ public boolean uploadPersonalNote(@NonNull Geocache cache); @@ -165,7 +146,6 @@ public interface IConnector { /** * Resetting of modified coordinates on website to details * - * @param cache * @return success */ public boolean deleteModifiedCoordinates(@NonNull Geocache cache); @@ -173,8 +153,6 @@ public interface IConnector { /** * Uploading modified coordinates to website * - * @param cache - * @param wpt * @return success */ public boolean uploadModifiedCoordinates(@NonNull Geocache cache, @NonNull Geopoint wpt); @@ -183,7 +161,6 @@ public interface IConnector { * Return {@code true} if this connector is active for online interaction (download details, do searches, ...). If * this is {@code false}, the connector will still be used for already stored offline caches. * - * @return */ public boolean isActive(); @@ -200,8 +177,6 @@ public interface IConnector { * Check if the cache information is complete enough to be * able to log online. * - * @param geocache - * @return */ public boolean canLog(@NonNull Geocache geocache); @@ -218,8 +193,6 @@ public interface IConnector { * Get the list of <b>potentially</b> possible log types for a cache. Those may still be filtered further during the * actual logging activity. * - * @param geocache - * @return */ @NonNull public List<LogType> getPossibleLogTypes(@NonNull Geocache geocache); @@ -228,16 +201,12 @@ public interface IConnector { * Get the GPX id for a waypoint when exporting. For some connectors there is an inherent name logic, * for others its just the 'prefix'. * - * @param prefix - * @return */ - public String getWaypointGpxId(String prefix, String geocode); + public String getWaypointGpxId(String prefix, @NonNull String geocode); /** * Get the 'prefix' (key) for a waypoint from the 'name' in the GPX file * - * @param name - * @return */ @NonNull public String getWaypointPrefix(String name); @@ -245,14 +214,12 @@ public interface IConnector { /** * Get the maximum value for Terrain * - * @return */ public int getMaxTerrain(); /** * Get a user readable collection of all online features of this connector. * - * @return */ @NonNull public Collection<String> getCapabilities(); diff --git a/main/src/cgeo/geocaching/connector/ILoggingManager.java b/main/src/cgeo/geocaching/connector/ILoggingManager.java index 40a5377..2b0a067 100644 --- a/main/src/cgeo/geocaching/connector/ILoggingManager.java +++ b/main/src/cgeo/geocaching/connector/ILoggingManager.java @@ -16,13 +16,8 @@ public interface ILoggingManager { /** * Post a log for a cache online * - * @param logType - * @param date - * @param log * @param logPassword * optional, maybe null - * @param trackableLogs - * @return */ @NonNull LogResult postLog(@NonNull LogType logType, diff --git a/main/src/cgeo/geocaching/connector/UnknownConnector.java b/main/src/cgeo/geocaching/connector/UnknownConnector.java index fcf1152..cabf03e 100644 --- a/main/src/cgeo/geocaching/connector/UnknownConnector.java +++ b/main/src/cgeo/geocaching/connector/UnknownConnector.java @@ -4,6 +4,7 @@ import cgeo.geocaching.Geocache; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; class UnknownConnector extends AbstractConnector { @@ -14,9 +15,9 @@ class UnknownConnector extends AbstractConnector { } @Override - @NonNull + @Nullable public String getCacheUrl(@NonNull final Geocache cache) { - return StringUtils.EMPTY; + return null; } @Override @@ -42,7 +43,8 @@ class UnknownConnector extends AbstractConnector { } @Override - public String getGeocodeFromUrl(final String url) { + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { return null; } diff --git a/main/src/cgeo/geocaching/connector/WaymarkingConnector.java b/main/src/cgeo/geocaching/connector/WaymarkingConnector.java index 5a6f362..3361341 100644 --- a/main/src/cgeo/geocaching/connector/WaymarkingConnector.java +++ b/main/src/cgeo/geocaching/connector/WaymarkingConnector.java @@ -4,6 +4,7 @@ import cgeo.geocaching.Geocache; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; class WaymarkingConnector extends AbstractConnector { @@ -41,4 +42,20 @@ class WaymarkingConnector extends AbstractConnector { public boolean canHandle(@NonNull final String geocode) { return StringUtils.startsWith(geocode, "WM"); } + + @Override + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { + // coord.info URLs + String code = StringUtils.substringAfterLast(url, "coord.info/"); + if (code != null && canHandle(code)) { + return code; + } + // waymarking URLs http://www.waymarking.com/waymarks/WMNCDT_American_Legion_Flagpole_1983_University_of_Oregon + code = StringUtils.substringBetween(url, "waymarks/", "_"); + if (code != null && canHandle(code)) { + return code; + } + return null; + } } diff --git a/main/src/cgeo/geocaching/connector/capability/ILogin.java b/main/src/cgeo/geocaching/connector/capability/ILogin.java index 003ccf4..437eec8 100644 --- a/main/src/cgeo/geocaching/connector/capability/ILogin.java +++ b/main/src/cgeo/geocaching/connector/capability/ILogin.java @@ -27,14 +27,12 @@ public interface ILogin extends IConnector { /** * Returns the status of the last {@link #login(Handler, Context)} request. * - * @return */ boolean isLoggedIn(); /** * User-centered string describing the current login/connection status * - * @return */ String getLoginStatusString(); @@ -42,7 +40,6 @@ public interface ILogin extends IConnector { * Name the user has in this connector or empty string if not applicable. * It might be necessary to execute {@link #login(Handler, Context)} before this information is valid. * - * @return */ String getUserName(); @@ -51,7 +48,6 @@ public interface ILogin extends IConnector { * Normally retrieved/updated with {@link #login(Handler, Context)}. * Might be stale as changes on the connectors site are generally not notified. * - * @return */ int getCachesFound(); diff --git a/main/src/cgeo/geocaching/connector/capability/IgnoreCapability.java b/main/src/cgeo/geocaching/connector/capability/IgnoreCapability.java new file mode 100644 index 0000000..5eca3f2 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/capability/IgnoreCapability.java @@ -0,0 +1,14 @@ +package cgeo.geocaching.connector.capability; + +import cgeo.geocaching.Geocache; +import cgeo.geocaching.connector.IConnector; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * Connector capability to ignore caches. + */ +public interface IgnoreCapability extends IConnector { + public boolean canIgnoreCache(final @NonNull Geocache cache); + public void ignoreCache(final @NonNull Geocache cache); +} diff --git a/main/src/cgeo/geocaching/connector/ec/ECConnector.java b/main/src/cgeo/geocaching/connector/ec/ECConnector.java index 15c2dc2..68dbee7 100644 --- a/main/src/cgeo/geocaching/connector/ec/ECConnector.java +++ b/main/src/cgeo/geocaching/connector/ec/ECConnector.java @@ -234,4 +234,14 @@ public class ECConnector extends AbstractConnector implements ISearchByGeocode, return R.string.pref_ecpassword; } + @Override + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { + final String geocode = "EC" + StringUtils.substringAfter(url, "extremcaching.com/index.php/output-2/"); + if (canHandle(geocode)) { + return geocode; + } + return super.getGeocodeFromUrl(url); + } + } diff --git a/main/src/cgeo/geocaching/connector/ec/ECLogin.java b/main/src/cgeo/geocaching/connector/ec/ECLogin.java index 3ae8298..94b450b 100644 --- a/main/src/cgeo/geocaching/connector/ec/ECLogin.java +++ b/main/src/cgeo/geocaching/connector/ec/ECLogin.java @@ -88,7 +88,6 @@ public class ECLogin extends AbstractLogin { /** * Check if the user has been logged in when he retrieved the data. * - * @param data * @return <code>true</code> if user is logged in, <code>false</code> otherwise */ private boolean getLoginStatus(@Nullable final String data) { diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index e43b9b5..2349392 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -19,6 +19,7 @@ import cgeo.geocaching.connector.capability.ISearchByGeocode; import cgeo.geocaching.connector.capability.ISearchByKeyword; import cgeo.geocaching.connector.capability.ISearchByOwner; import cgeo.geocaching.connector.capability.ISearchByViewPort; +import cgeo.geocaching.connector.capability.IgnoreCapability; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.loaders.RecaptchaReceiver; import cgeo.geocaching.location.Geopoint; @@ -47,7 +48,7 @@ import java.io.File; import java.util.List; import java.util.regex.Pattern; -public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort, ISearchByKeyword, ILogin, ICredentials, ISearchByOwner, ISearchByFinder, FieldNotesCapability { +public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort, ISearchByKeyword, ILogin, ICredentials, ISearchByOwner, ISearchByFinder, FieldNotesCapability, IgnoreCapability { @NonNull private static final String CACHE_URL_SHORT = "http://coord.info/"; @@ -305,7 +306,8 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, } @Override - public String getGeocodeFromUrl(final String url) { + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { // coord.info URLs String code = StringUtils.substringAfterLast(url, "coord.info/"); if (code != null && canHandle(code)) { @@ -375,7 +377,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, } @Override - public String getWaypointGpxId(final String prefix, final String geocode) { + public String getWaypointGpxId(final String prefix, @NonNull final String geocode) { String gpxId = prefix; if (StringUtils.isNotBlank(geocode) && geocode.length() > 2) { gpxId += geocode.substring(2); @@ -480,4 +482,14 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, return true; } + @Override + public boolean canIgnoreCache(@NonNull final Geocache cache) { + return StringUtils.isNotEmpty(cache.getType().wptTypeId); + } + + @Override + public void ignoreCache(@NonNull final Geocache cache) { + GCParser.ignoreCache(cache); + } + } diff --git a/main/src/cgeo/geocaching/connector/gc/GCLogin.java b/main/src/cgeo/geocaching/connector/gc/GCLogin.java index 035176b..71c31c1 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCLogin.java +++ b/main/src/cgeo/geocaching/connector/gc/GCLogin.java @@ -166,7 +166,6 @@ public class GCLogin extends AbstractLogin { /** * Check if the user has been logged in when he retrieved the data. * - * @param page * @return <code>true</code> if user is logged in, <code>false</code> otherwise */ boolean getLoginStatus(@Nullable final String page) { @@ -412,8 +411,6 @@ public class GCLogin extends AbstractLogin { /** * POST HTTP request. Do the request a second time if the user is not logged in * - * @param uri - * @return */ String postRequestLogged(final String uri, final Parameters params) { final String data = Network.getResponseData(Network.postRequest(uri, params)); @@ -433,9 +430,6 @@ public class GCLogin extends AbstractLogin { /** * GET HTTP request. Do the request a second time if the user is not logged in * - * @param uri - * @param params - * @return */ @Nullable String getRequestLogged(@NonNull final String uri, @Nullable final Parameters params) { @@ -459,8 +453,6 @@ public class GCLogin extends AbstractLogin { * Unfortunately the cache details page contains user generated whitespace in the personal note, therefore we cannot * remove the white space from cache details pages. * - * @param uri - * @return */ private static boolean canRemoveWhitespace(final String uri) { return !StringUtils.contains(uri, "cache_details"); diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java index 1571faa..243d84c 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCMap.java +++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java @@ -11,8 +11,8 @@ import cgeo.geocaching.location.Geopoint; import cgeo.geocaching.location.GeopointFormatter.Format; import cgeo.geocaching.location.Units; import cgeo.geocaching.location.Viewport; -import cgeo.geocaching.maps.LiveMapStrategy.Strategy; -import cgeo.geocaching.maps.LiveMapStrategy.StrategyFlag; +import cgeo.geocaching.maps.LivemapStrategy; +import cgeo.geocaching.maps.LivemapStrategy.Flag; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.sensors.Sensors; import cgeo.geocaching.settings.Settings; @@ -110,7 +110,7 @@ public class GCMap { * Retrieved data. * @return SearchResult. Never null. */ - public static SearchResult parseMapJSON(final String data, final Tile tile, final Bitmap bitmap, final Strategy strategy) { + public static SearchResult parseMapJSON(final String data, final Tile tile, final Bitmap bitmap, final LivemapStrategy strategy) { final SearchResult searchResult = new SearchResult(); try { @@ -185,7 +185,7 @@ public class GCMap { cache.setGeocode(id); cache.setName(nameCache.get(id)); cache.setCoords(tile.getCoord(xy), tile.getZoomLevel()); - if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && bitmap != null) { + if (strategy.flags.contains(LivemapStrategy.Flag.PARSE_TILES) && bitmap != null) { for (final UTFGridPosition singlePos : singlePositions.get(id)) { if (IconDecoder.parseMapPNG(cache, bitmap, singlePos, tile.getZoomLevel())) { break; // cache parsed @@ -226,14 +226,13 @@ public class GCMap { * Area to search * @param tokens * Live map tokens - * @return */ @NonNull public static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens) { final int speed = (int) Sensors.getInstance().currentGeo().getSpeed() * 60 * 60 / 1000; // in km/h - Strategy strategy = Settings.getLiveMapStrategy(); - if (strategy == Strategy.AUTO) { - strategy = speed >= 30 ? Strategy.FAST : Strategy.DETAILED; + LivemapStrategy strategy = Settings.getLiveMapStrategy(); + if (strategy == LivemapStrategy.AUTO) { + strategy = speed >= 30 ? LivemapStrategy.FAST : LivemapStrategy.DETAILED; } final SearchResult result = searchByViewport(viewport, tokens, strategy); @@ -257,10 +256,9 @@ public class GCMap { * Live map tokens * @param strategy * Strategy for data retrieval and parsing, @see Strategy - * @return */ @NonNull - private static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens, final Strategy strategy) { + private static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens, final LivemapStrategy strategy) { Log.d("GCMap.searchByViewport" + viewport.toString()); final SearchResult searchResult = new SearchResult(); @@ -269,7 +267,7 @@ public class GCMap { searchResult.setUrl(viewport.getCenter().format(Format.LAT_LON_DECMINUTE)); } - if (strategy.flags.contains(StrategyFlag.LOAD_TILES)) { + if (strategy.flags.contains(LivemapStrategy.Flag.LOAD_TILES)) { final Set<Tile> tiles = Tile.getTilesForViewport(viewport); if (Settings.isDebug()) { @@ -339,7 +337,7 @@ public class GCMap { } } - if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) { + if (strategy.flags.contains(Flag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) { final Geopoint center = viewport.getCenter(); if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) { //FIXME We don't have a RecaptchaReceiver!? @@ -360,7 +358,6 @@ public class GCMap { * * @param typeToDisplay * - cache type to omit from exclusion list so it gets displayed - * @return * * cache types for live map filter: * 2 = traditional, 9 = ape, 5 = letterbox diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index d5ea8c4..d0a90bb 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -57,7 +57,6 @@ import rx.functions.Action1; import rx.functions.Func0; import rx.functions.Func2; import rx.schedulers.Schedulers; -import rx.util.async.Async; import android.net.Uri; import android.text.Html; @@ -65,6 +64,7 @@ import android.text.Html; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.text.Collator; import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; @@ -304,12 +304,13 @@ public abstract class GCParser { if (!cids.isEmpty() && (Settings.isGCPremiumMember() || showCaptcha) && ((recaptchaReceiver == null || StringUtils.isBlank(recaptchaReceiver.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) { Log.i("Trying to get .loc for " + cids.size() + " caches"); - final Observable<Set<Geocache>> storedCaches = Async.start(new Func0<Set<Geocache>>() { + final Observable<Set<Geocache>> storedCaches = Observable.defer(new Func0<Observable<Set<Geocache>>>() { @Override - public Set<Geocache> call() { - return DataStore.loadCaches(Geocache.getGeocodes(caches), LoadFlags.LOAD_CACHE_OR_DB); + public Observable<Set<Geocache>> call() { + return Observable.just(DataStore.loadCaches(Geocache.getGeocodes(caches), LoadFlags.LOAD_CACHE_OR_DB)); } - }, Schedulers.io()); + }).subscribeOn(Schedulers.io()).cache(); + storedCaches.subscribe(); // Force asynchronous start of database loading try { // get coordinates for parsed caches @@ -987,22 +988,22 @@ public abstract class GCParser { * Observable that fetches a list of pocket queries. Returns a single element (which may be an empty list). * Executes on the network scheduler. */ - public static final Observable<List<PocketQueryList>> searchPocketQueryListObservable = Async.fromCallable(new Func0<List<PocketQueryList>>() { + public static final Observable<List<PocketQueryList>> searchPocketQueryListObservable = Observable.defer(new Func0<Observable<List<PocketQueryList>>>() { @Override - public List<PocketQueryList> call() { + public Observable<List<PocketQueryList>> call() { final Parameters params = new Parameters(); final String page = GCLogin.getInstance().getRequestLogged("http://www.geocaching.com/pocket/default.aspx", params); if (StringUtils.isBlank(page)) { Log.e("GCParser.searchPocketQueryList: No data from server"); - return Collections.emptyList(); + return Observable.just(Collections.<PocketQueryList>emptyList()); } final String subPage = StringUtils.substringAfter(page, "class=\"PocketQueryListTable"); if (StringUtils.isEmpty(subPage)) { Log.e("GCParser.searchPocketQueryList: class \"PocketQueryListTable\" not found on page"); - return Collections.emptyList(); + return Observable.just(Collections.<PocketQueryList>emptyList()); } final List<PocketQueryList> list = new ArrayList<>(); @@ -1024,17 +1025,18 @@ public abstract class GCParser { } // just in case, lets sort the resulting list + final Collator collator = TextUtils.getCollator(); Collections.sort(list, new Comparator<PocketQueryList>() { @Override public int compare(final PocketQueryList left, final PocketQueryList right) { - return String.CASE_INSENSITIVE_ORDER.compare(left.getName(), right.getName()); + return collator.compare(left.getName(), right.getName()); } }); - return list; + return Observable.just(list); } - }, RxUtils.networkScheduler); + }).subscribeOn(RxUtils.networkScheduler); public static ImmutablePair<StatusCode, String> postLog(final String geocode, final String cacheid, final String[] viewstates, final LogType logType, final int year, final int month, final int day, @@ -1985,4 +1987,25 @@ public abstract class GCParser { return false; } + public static boolean ignoreCache(@NonNull final Geocache cache) { + final String uri = "http://www.geocaching.com/bookmarks/ignore.aspx?guid=" + cache.getGuid() + "&WptTypeID=" + cache.getType().wptTypeId; + final String page = GCLogin.getInstance().postRequestLogged(uri, null); + + if (StringUtils.isBlank(page)) { + Log.e("GCParser.ignoreCache: No data from server"); + return false; + } + + final String[] viewstates = GCLogin.getViewstates(page); + + final Parameters params = new Parameters( + "__EVENTTARGET", "", + "__EVENTARGUMENT", "", + "ctl00$ContentBody$btnYes", "Yes. Ignore it."); + + GCLogin.putViewstates(params, viewstates); + final String response = Network.getResponseData(Network.postRequest(uri, params)); + + return StringUtils.contains(response, "<p class=\"Success\">"); + } } diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java index 93b61f9..dd6371b 100644 --- a/main/src/cgeo/geocaching/connector/gc/Tile.java +++ b/main/src/cgeo/geocaching/connector/gc/Tile.java @@ -15,7 +15,6 @@ import org.eclipse.jdt.annotation.NonNull; import rx.Observable; import rx.functions.Func0; -import rx.util.async.Async; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -144,7 +143,6 @@ public class Tile { * First point * @param right * Second point - * @return */ static int calcZoomLon(final Geopoint left, final Geopoint right, final int numberOfTiles) { @@ -177,7 +175,6 @@ public class Tile { * First point * @param top * Second point - * @return */ static int calcZoomLat(final Geopoint bottom, final Geopoint top, final int numberOfTiles) { @@ -208,8 +205,6 @@ public class Tile { * Calculates the inverted hyperbolic sine * (after Bronstein, Semendjajew: Taschenbuch der Mathematik) * - * @param x - * @return */ private static double asinh(final double x) { return Math.log(x + Math.sqrt(x * x + 1.0)); @@ -241,12 +236,12 @@ public class Tile { static Observable<String> requestMapInfo(final String url, final Parameters params, final String referer) { final HttpResponse response = Network.getRequest(url, params, new Parameters("Referer", referer)); - return Async.start(new Func0<String>() { + return Observable.defer(new Func0<Observable<String>>() { @Override - public String call() { - return Network.getResponseData(response); + public Observable<String> call() { + return Observable.just(Network.getResponseData(response)); } - }, RxUtils.networkScheduler); + }).subscribeOn(RxUtils.networkScheduler); } /** Request .png image for a tile. Return as soon as the request has been made, before the answer has been @@ -256,17 +251,17 @@ public class Tile { */ static Observable<Bitmap> requestMapTile(final Parameters params) { final HttpResponse response = Network.getRequest(GCConstants.URL_MAP_TILE, params, new Parameters("Referer", GCConstants.URL_LIVE_MAP)); - return Async.start(new Func0<Bitmap>() { + return Observable.defer(new Func0<Observable<Bitmap>>() { @Override - public Bitmap call() { + public Observable<Bitmap> call() { try { - return response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null; + return Observable.just(response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null); } catch (final IOException e) { Log.e("Tile.requestMapTile() ", e); - return null; + return Observable.just(null); } } - }, RxUtils.computationScheduler); + }).subscribeOn(RxUtils.computationScheduler); } public boolean containsPoint(final @NonNull ICoordinates point) { @@ -281,8 +276,6 @@ public class Tile { * Calculate needed tiles for the given viewport to cover it with * max 2x2 tiles * - * @param viewport - * @return */ protected static Set<Tile> getTilesForViewport(final Viewport viewport) { return getTilesForViewport(viewport, 2, Tile.ZOOMLEVEL_MIN); @@ -293,10 +286,6 @@ public class Tile { * You can define the minimum number of tiles on the longer axis * and/or the minimum zoom level. * - * @param viewport - * @param tilesOnAxis - * @param minZoom - * @return */ protected static Set<Tile> getTilesForViewport(final Viewport viewport, final int tilesOnAxis, final int minZoom) { final Set<Tile> tiles = new HashSet<>(); diff --git a/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java index 9de7e1e..f5cd208 100644 --- a/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java +++ b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java @@ -36,7 +36,6 @@ final class UTFGridPosition { /** * @param key * Key in the format (xx, xx) - * @return */ static UTFGridPosition fromString(final String key) { final MatcherWrapper matcher = new MatcherWrapper(UTFGridPosition.PATTERN_JSON_KEY, key); diff --git a/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java b/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java index 71adcbd..c9e01a2 100644 --- a/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java +++ b/main/src/cgeo/geocaching/connector/gc/UncertainProperty.java @@ -4,7 +4,6 @@ package cgeo.geocaching.connector.gc; /** * Property with certainty. When merging properties, the one with higher certainty wins. * - * @param <T> */ public class UncertainProperty<T> { diff --git a/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java b/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java index acf7b48..5e5151a 100644 --- a/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java +++ b/main/src/cgeo/geocaching/connector/oc/IOCAuthParams.java @@ -7,7 +7,6 @@ public interface IOCAuthParams { /** * The site name: 'www.opencaching...' * - * @return */ @NonNull String getSite(); @@ -15,56 +14,48 @@ public interface IOCAuthParams { /** * ResId of the Consumer key * - * @return */ int getCKResId(); /** * ResId of the Consumer secret * - * @return */ int getCSResId(); /** * ResId of the Authorization title * - * @return */ int getAuthTitleResId(); /** * Preference key of the public token * - * @return */ int getTokenPublicPrefKey(); /** * Preference key of the secret token * - * @return */ int getTokenSecretPrefKey(); /** * Preference key of the temporary public token (OAuth) * - * @return */ int getTempTokenPublicPrefKey(); /** * Preference key of the temporary secret token (OAuth) * - * @return */ int getTempTokenSecretPrefKey(); /** * The URI to use as a callback (OAuth) * - * @return */ @NonNull String getCallbackUri(); diff --git a/main/src/cgeo/geocaching/connector/oc/OCCZConnector.java b/main/src/cgeo/geocaching/connector/oc/OCCZConnector.java new file mode 100644 index 0000000..ee4330a --- /dev/null +++ b/main/src/cgeo/geocaching/connector/oc/OCCZConnector.java @@ -0,0 +1,34 @@ +package cgeo.geocaching.connector.oc; + +import cgeo.geocaching.utils.Log; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +public class OCCZConnector extends OCConnector { + + private static final String GEOCODE_PREFIX = "OZ"; + + public OCCZConnector() { + super("OpenCaching.CZ", "www.opencaching.cz", GEOCODE_PREFIX); + } + + @Override + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { + if (!StringUtils.containsIgnoreCase(url, "opencaching.cz")) { + return null; + } + final String id = StringUtils.substringAfter(url, "cacheid="); + try { + final String geocode = GEOCODE_PREFIX + StringUtils.leftPad(Integer.toHexString(Integer.parseInt(id)), 4, '0'); + if (canHandle(geocode)) { + return geocode; + } + } catch (final NumberFormatException e) { + Log.e("Unexpected URL for opencaching.cz " + url); + } + return super.getGeocodeFromUrl(url); + } +} diff --git a/main/src/cgeo/geocaching/connector/oc/OCConnector.java b/main/src/cgeo/geocaching/connector/oc/OCConnector.java index 8ac457b..6d7b23a 100644 --- a/main/src/cgeo/geocaching/connector/oc/OCConnector.java +++ b/main/src/cgeo/geocaching/connector/oc/OCConnector.java @@ -5,7 +5,9 @@ import cgeo.geocaching.R; import cgeo.geocaching.connector.AbstractConnector; import cgeo.geocaching.enumerations.LogType; +import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import java.util.Arrays; import java.util.List; @@ -83,4 +85,24 @@ public class OCConnector extends AbstractConnector { return STANDARD_LOG_TYPES; } + + @Override + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { + // different opencaching installations have different supported URLs + + // host.tld/geocode + final String shortHost = StringUtils.remove(getHost(), "www."); + String geocode = StringUtils.substringAfter(url, shortHost + "/"); + if (canHandle(geocode)) { + return geocode; + } + + // host.tld/viewcache.php?wp=geocode + geocode = StringUtils.substringAfter(url, shortHost + "/viewcache.php?wp="); + if (canHandle(geocode)) { + return geocode; + } + return super.getGeocodeFromUrl(url); + } } diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java index 275a103..e7d4e6f 100644 --- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java @@ -30,6 +30,7 @@ import cgeo.geocaching.network.OAuth; import cgeo.geocaching.network.OAuthTokens; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.settings.Settings; +import cgeo.geocaching.utils.HtmlUtils; import cgeo.geocaching.utils.JsonUtils; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.SynchronizedDateFormat; @@ -62,8 +63,16 @@ import java.util.Map; import java.util.TimeZone; import java.util.regex.Pattern; +/** + * Client for the OpenCaching API (Okapi). + * + * @see <a href="http://www.opencaching.de/okapi/introduction.html">Okapi overview</a> + * + */ final class OkapiClient { + private static final String PARAMETER_LOGCOUNT_VALUE = "all"; + private static final String PARAMETER_LOGCOUNT_KEY = "lpc"; private static final char SEPARATOR = '|'; private static final String SEPARATOR_STRING = Character.toString(SEPARATOR); private static final SynchronizedDateFormat LOG_DATE_FORMAT = new SynchronizedDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC"), Locale.US); @@ -149,6 +158,7 @@ final class OkapiClient { params.add("fields", getFullFields(ocapiConn)); params.add("attribution_append", "none"); + params.add(PARAMETER_LOGCOUNT_KEY, PARAMETER_LOGCOUNT_VALUE); final JSONResult result = request(ocapiConn, OkapiService.SERVICE_CACHE, params); @@ -458,7 +468,7 @@ final class OkapiClient { parseUser(logResponse.get(LOG_USER)), parseDate(logResponse.get(LOG_DATE).asText()).getTime(), parseLogType(logResponse.get(LOG_TYPE).asText()), - logResponse.get(LOG_COMMENT).asText().trim()); + HtmlUtils.removeExtraParagraph(logResponse.get(LOG_COMMENT).asText().trim())); result.add(log); } catch (final NullPointerException e) { Log.e("OkapiClient.parseLogs", e); diff --git a/main/src/cgeo/geocaching/connector/ox/OXConnector.java b/main/src/cgeo/geocaching/connector/ox/OXConnector.java index 41035d1..d1db301 100644 --- a/main/src/cgeo/geocaching/connector/ox/OXConnector.java +++ b/main/src/cgeo/geocaching/connector/ox/OXConnector.java @@ -14,6 +14,7 @@ import cgeo.geocaching.location.Viewport; import cgeo.geocaching.settings.Settings; import cgeo.geocaching.utils.CancellableHandler; +import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -109,4 +110,14 @@ public class OXConnector extends AbstractConnector implements ISearchByCenter, I } return new SearchResult(caches); } + + @Override + @Nullable + public String getGeocodeFromUrl(@NonNull final String url) { + final String geocode = StringUtils.substringAfter(url, "http://www.opencaching.com/de/#!geocache/"); + if (canHandle(geocode)) { + return geocode; + } + return super.getGeocodeFromUrl(url); + } } diff --git a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java index 7896826..25f66f4 100644 --- a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java +++ b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java @@ -29,7 +29,6 @@ public class OXGPXParser extends GPX10Parser { * The short description of OX caches contains "title by owner, type(T/D/Awesomeness)". That is a lot of * duplication. Additionally a space between type and (T/D/Awesomeness) is introduced. * - * @param cache */ private static void removeTitleFromShortDescription(final @NonNull Geocache cache) { cache.setShortDescription(StringUtils.replace(StringUtils.trim(StringUtils.substringAfterLast(cache.getShortDescription(), ",")), "(", " (")); diff --git a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java index b6792f0..6f9b21a 100644 --- a/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/GeokretyConnector.java @@ -26,6 +26,7 @@ public class GeokretyConnector extends AbstractTrackableConnector { } @Override + @Nullable public Trackable searchTrackable(final String geocode, final String guid, final String id) { final String page = Network.getResponseData(Network.getRequest("http://geokrety.org/export2.php?gkid=" + getId(geocode))); if (page == null) { @@ -48,7 +49,12 @@ public class GeokretyConnector extends AbstractTrackableConnector { public @Nullable String getTrackableCodeFromUrl(@NonNull final String url) { // http://geokrety.org/konkret.php?id=38545 - final String id = StringUtils.substringAfterLast(url, "konkret.php?id="); + String id = StringUtils.substringAfterLast(url, "konkret.php?id="); + if (StringUtils.isNumeric(id)) { + return geocode(Integer.parseInt(id)); + } + // http://geokretymap.org/38545 + id = StringUtils.substringAfterLast(url, "geokretymap.org/"); if (StringUtils.isNumeric(id)) { return geocode(Integer.parseInt(id)); } @@ -58,8 +64,6 @@ public class GeokretyConnector extends AbstractTrackableConnector { /** * Get geocode from geokrety id * - * @param id - * @return */ public static String geocode(final int id) { return String.format("GK%04X", id); diff --git a/main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java b/main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java new file mode 100644 index 0000000..dcd618c --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/SwaggieConnector.java @@ -0,0 +1,51 @@ +package cgeo.geocaching.connector.trackable; + +import cgeo.geocaching.Trackable; +import cgeo.geocaching.network.Network; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import java.util.regex.Pattern; + +public final class SwaggieConnector extends AbstractTrackableConnector { + + private static final Pattern PATTERN_SW_CODE = Pattern.compile("SW[0-9]{4}"); + + @Override + public boolean canHandleTrackable(final String geocode) { + return geocode != null && PATTERN_SW_CODE.matcher(geocode).matches(); + } + + @Override + @NonNull + public String getUrl(@NonNull final Trackable trackable) { + return getUrl(trackable.getGeocode()); + } + + @Override + @Nullable + public Trackable searchTrackable(final String geocode, final String guid, final String id) { + final String page = Network.getResponseData(Network.getRequest(getUrl(geocode))); + if (page == null) { + return null; + } + return SwaggieParser.parse(page); + } + + @Override + @Nullable + public String getTrackableCodeFromUrl(@NonNull final String url) { + final String geocode = StringUtils.upperCase(StringUtils.substringAfterLast(url, "swaggie/")); + if (canHandleTrackable(geocode)) { + return geocode; + } + return null; + } + + private static String getUrl(final String geocode) { + return "http://geocaching.com.au/swaggie/" + geocode; + } + +} diff --git a/main/src/cgeo/geocaching/connector/trackable/SwaggieParser.java b/main/src/cgeo/geocaching/connector/trackable/SwaggieParser.java new file mode 100644 index 0000000..1883056 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/trackable/SwaggieParser.java @@ -0,0 +1,55 @@ +package cgeo.geocaching.connector.trackable; + +import cgeo.geocaching.Trackable; +import cgeo.geocaching.utils.TextUtils; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import java.util.regex.Pattern; + +final class SwaggieParser { + + private SwaggieParser() { + // utility class + } + + private static final Pattern PATTERN_NAME = Pattern.compile(Pattern.quote("<h1><a") + ".*?>(.*?)<"); + private static final Pattern PATTERN_GEOCODE = Pattern.compile(Pattern.quote("'/swaggie/") + "(.*?)'"); + private static final Pattern PATTERN_DESCRIPTION = Pattern.compile(Pattern.quote("'swaggie_description'>") + "(.*?)</div"); + private static final Pattern PATTERN_OWNER = Pattern.compile(">([^<]*?)</a> released"); + + @Nullable + public static Trackable parse(@NonNull final String page) { + final Trackable trackable = new Trackable(); + final String name = TextUtils.getMatch(page, PATTERN_NAME, null); + if (StringUtils.isEmpty(name)) { + return null; + } + trackable.setName(name); + + final String geocode = TextUtils.getMatch(page, PATTERN_GEOCODE, null); + if (StringUtils.isEmpty(geocode)) { + return null; + } + trackable.setGeocode(geocode); + + final String description = StringUtils.trim(TextUtils.getMatch(page, PATTERN_DESCRIPTION, StringUtils.EMPTY)); + if (StringUtils.isEmpty(description)) { + return null; + } + trackable.setDetails(description); + + final String owner = StringUtils.trim(TextUtils.getMatch(page, PATTERN_OWNER, StringUtils.EMPTY)); + if (StringUtils.isEmpty(owner)) { + return null; + } + trackable.setOwner(owner); + + trackable.setType("Swaggie"); + + return trackable; + } + +} diff --git a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java index 01c1897..1281683 100644 --- a/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/TrackableConnector.java @@ -21,6 +21,7 @@ public interface TrackableConnector { public boolean isLoggable(); + @Nullable public Trackable searchTrackable(String geocode, String guid, String id); @Nullable diff --git a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java index 5d825a3..665ebea 100644 --- a/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/TravelBugConnector.java @@ -36,6 +36,7 @@ public class TravelBugConnector extends AbstractTrackableConnector { } @Override + @Nullable public Trackable searchTrackable(final String geocode, final String guid, final String id) { return GCParser.searchTrackable(geocode, guid, id); } diff --git a/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java b/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java index 7e7e1b6..5fc7bf1 100644 --- a/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java +++ b/main/src/cgeo/geocaching/connector/trackable/UnknownTrackableConnector.java @@ -3,6 +3,7 @@ package cgeo.geocaching.connector.trackable; import cgeo.geocaching.Trackable; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; public class UnknownTrackableConnector extends AbstractTrackableConnector { @@ -18,6 +19,7 @@ public class UnknownTrackableConnector extends AbstractTrackableConnector { } @Override + @Nullable public Trackable searchTrackable(final String geocode, final String guid, final String id) { return null; } |