aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/Geocache.java
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/Geocache.java')
-rw-r--r--main/src/cgeo/geocaching/Geocache.java217
1 files changed, 133 insertions, 84 deletions
diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java
index 836cccb..3c69197 100644
--- a/main/src/cgeo/geocaching/Geocache.java
+++ b/main/src/cgeo/geocaching/Geocache.java
@@ -5,13 +5,13 @@ import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.connector.ILoggingManager;
import cgeo.geocaching.connector.capability.ISearchByCenter;
import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.gc.GCConstants;
import cgeo.geocaching.connector.gc.Tile;
import cgeo.geocaching.enumerations.CacheAttribute;
-import cgeo.geocaching.enumerations.CacheRealm;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
@@ -23,6 +23,7 @@ import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.files.GPXParser;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.network.HtmlImage;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.LazyInitializedList;
import cgeo.geocaching.utils.Log;
@@ -47,8 +48,8 @@ import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
@@ -85,7 +86,6 @@ public class Geocache implements ICache, IWaypoint {
private String location = null;
private Geopoint coords = null;
private boolean reliableLatLon = false;
- private Double elevation = null;
private String personalNote = null;
/**
* lazy initialized
@@ -106,20 +106,20 @@ public class Geocache implements ICache, IWaypoint {
private float myVote = 0; // valid ratings are larger than zero
private int inventoryItems = 0;
private boolean onWatchlist = false;
- private List<String> attributes = new LazyInitializedList<String>() {
+ private final List<String> attributes = new LazyInitializedList<String>() {
@Override
public List<String> call() {
return cgData.loadAttributes(geocode);
}
};
- private List<Waypoint> waypoints = new LazyInitializedList<Waypoint>() {
+ private final List<Waypoint> waypoints = new LazyInitializedList<Waypoint>() {
@Override
public List<Waypoint> call() {
return cgData.loadWaypoints(geocode);
}
};
private List<Image> spoilers = null;
- private List<LogEntry> logs = new LazyInitializedList<LogEntry>() {
+ private final List<LogEntry> logs = new LazyInitializedList<LogEntry>() {
@Override
public List<LogEntry> call() {
return cgData.loadLogs(geocode);
@@ -135,6 +135,7 @@ public class Geocache implements ICache, IWaypoint {
private String nameForSorting;
private final EnumSet<StorageLocation> storageLocation = EnumSet.of(StorageLocation.HEAP);
private boolean finalDefined = false;
+ private boolean logPasswordRequired = false;
private int zoomlevel = Tile.ZOOMLEVEL_MAX + 1;
private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");
@@ -175,7 +176,9 @@ public class Geocache implements ICache, IWaypoint {
}
/**
- * Gather missing information from another cache object.
+ * Gather missing information for new Geocache object from the stored Geocache object.
+ * This is called in the new Geocache parsed from website to set information not yet
+ * parsed.
*
* @param other
* the other version, or null if non-existent
@@ -187,6 +190,8 @@ public class Geocache implements ICache, IWaypoint {
}
updated = System.currentTimeMillis();
+ // if parsed cache is not yet detailed and stored is, the information of
+ // the parsed cache will be overwritten
if (!detailed && (other.detailed || zoomlevel < other.zoomlevel)) {
detailed = other.detailed;
detailedUpdate = other.detailedUpdate;
@@ -194,15 +199,19 @@ public class Geocache implements ICache, IWaypoint {
cacheType = other.cacheType;
zoomlevel = other.zoomlevel;
// boolean values must be enumerated here. Other types are assigned outside this if-statement
+ // TODO: check whether a search or a live map systematically returns those, in which case
+ // we want to keep the most recent one instead of getting information from the previously
+ // stored data. This is the case for "archived" for example which has been taken out of this
+ // list.
premiumMembersOnly = other.premiumMembersOnly;
reliableLatLon = other.reliableLatLon;
- archived = other.archived;
found = other.found;
disabled = other.disabled;
favorite = other.favorite;
onWatchlist = other.onWatchlist;
logOffline = other.logOffline;
finalDefined = other.finalDefined;
+ archived = other.archived;
}
/*
@@ -269,11 +278,14 @@ public class Geocache implements ICache, IWaypoint {
if (coords == null) {
coords = other.coords;
}
- if (elevation == null) {
- elevation = other.elevation;
- }
- if (personalNote == null) { // don't use StringUtils.isBlank here. Otherwise we cannot recognize a note which was deleted on GC
+ // don't use StringUtils.isBlank here. Otherwise we cannot recognize a note which was deleted on GC
+ if (personalNote == null) {
personalNote = other.personalNote;
+ } else if (other.personalNote != null && !personalNote.equals(other.personalNote)) {
+ final PersonalNote myNote = new PersonalNote(this);
+ final PersonalNote otherNote = new PersonalNote(other);
+ final PersonalNote mergedNote = myNote.mergeWith(otherNote);
+ personalNote = mergedNote.toString();
}
if (StringUtils.isBlank(getShortDescription())) {
shortdesc = other.getShortDescription();
@@ -305,7 +317,7 @@ public class Geocache implements ICache, IWaypoint {
this.setWaypoints(other.waypoints, false);
}
else {
- ArrayList<Waypoint> newPoints = new ArrayList<Waypoint>(waypoints);
+ final ArrayList<Waypoint> newPoints = new ArrayList<Waypoint>(waypoints);
Waypoint.mergeWayPoints(newPoints, other.waypoints, false);
this.setWaypoints(newPoints, false);
}
@@ -332,12 +344,10 @@ public class Geocache implements ICache, IWaypoint {
// if cache has ORIGINAL type waypoint ... it is considered that it has modified coordinates, otherwise not
userModifiedCoords = false;
- if (waypoints != null) {
- for (Waypoint wpt : waypoints) {
- if (wpt.getWaypointType() == WaypointType.ORIGINAL) {
- userModifiedCoords = true;
- break;
- }
+ for (final Waypoint wpt : waypoints) {
+ if (wpt.getWaypointType() == WaypointType.ORIGINAL) {
+ userModifiedCoords = true;
+ break;
}
}
@@ -388,7 +398,6 @@ public class Geocache implements ICache, IWaypoint {
StringUtils.equalsIgnoreCase(cacheId, other.cacheId) &&
(direction != null ? direction.equals(other.direction) : null == other.direction) &&
(distance != null ? distance.equals(other.distance) : null == other.distance) &&
- (elevation != null ? elevation.equals(other.elevation) : null == other.elevation) &&
rating == other.rating &&
votes == other.votes &&
myVote == other.myVote &&
@@ -447,13 +456,13 @@ public class Geocache implements ICache, IWaypoint {
}
public void logVisit(final IAbstractActivity fromActivity) {
- if (StringUtils.isBlank(cacheId)) {
+ if (!getConnector().canLog(this)) {
fromActivity.showToast(((Activity) fromActivity).getResources().getString(R.string.err_cannot_log_visit));
return;
}
- Intent logVisitIntent = new Intent((Activity) fromActivity, VisitCacheActivity.class);
- logVisitIntent.putExtra(VisitCacheActivity.EXTRAS_ID, cacheId);
- logVisitIntent.putExtra(VisitCacheActivity.EXTRAS_GEOCODE, geocode);
+ final Intent logVisitIntent = new Intent((Activity) fromActivity, LogCacheActivity.class);
+ logVisitIntent.putExtra(LogCacheActivity.EXTRAS_ID, cacheId);
+ logVisitIntent.putExtra(LogCacheActivity.EXTRAS_GEOCODE, geocode);
((Activity) fromActivity).startActivity(logVisitIntent);
}
@@ -470,7 +479,7 @@ public class Geocache implements ICache, IWaypoint {
}
final boolean status = cgData.saveLogOffline(geocode, date.getTime(), logType, log);
- Resources res = fromActivity.getResources();
+ final Resources res = fromActivity.getResources();
if (status) {
ActivityMixin.showToast(fromActivity, res.getString(R.string.info_log_saved));
cgData.saveVisitDate(geocode);
@@ -482,35 +491,43 @@ public class Geocache implements ICache, IWaypoint {
}
}
+ public void clearOfflineLog() {
+ cgData.clearLogOffline(geocode);
+ notifyChange();
+ }
+
public List<LogType> getPossibleLogTypes() {
- final List<LogType> logTypes = new LinkedList<LogType>();
+ final List<LogType> logTypes = new ArrayList<LogType>();
if (isEventCache()) {
logTypes.add(LogType.WILL_ATTEND);
- logTypes.add(LogType.NOTE);
logTypes.add(LogType.ATTENDED);
- logTypes.add(LogType.NEEDS_ARCHIVE);
if (isOwner()) {
logTypes.add(LogType.ANNOUNCEMENT);
}
} else if (CacheType.WEBCAM == cacheType) {
logTypes.add(LogType.WEBCAM_PHOTO_TAKEN);
- logTypes.add(LogType.DIDNT_FIND_IT);
- logTypes.add(LogType.NOTE);
- logTypes.add(LogType.NEEDS_ARCHIVE);
- logTypes.add(LogType.NEEDS_MAINTENANCE);
} else {
logTypes.add(LogType.FOUND_IT);
+ }
+ if (!isEventCache()) {
logTypes.add(LogType.DIDNT_FIND_IT);
- logTypes.add(LogType.NOTE);
- logTypes.add(LogType.NEEDS_ARCHIVE);
+ }
+ logTypes.add(LogType.NOTE);
+ if (!isEventCache()) {
logTypes.add(LogType.NEEDS_MAINTENANCE);
}
if (isOwner()) {
logTypes.add(LogType.OWNER_MAINTENANCE);
- logTypes.add(LogType.TEMP_DISABLE_LISTING);
- logTypes.add(LogType.ENABLE_LISTING);
+ if (isDisabled()) {
+ logTypes.add(LogType.ENABLE_LISTING);
+ }
+ else {
+ logTypes.add(LogType.TEMP_DISABLE_LISTING);
+ }
logTypes.add(LogType.ARCHIVE);
- logTypes.remove(LogType.UPDATE_COORDINATES);
+ }
+ if (!isArchived() && !isOwner()) {
+ logTypes.add(LogType.NEEDS_ARCHIVE);
}
return logTypes;
}
@@ -551,12 +568,16 @@ public class Geocache implements ICache, IWaypoint {
return getConnector().supportsLogging();
}
+ public boolean supportsLogImages() {
+ return getConnector().supportsLogImages();
+ }
+
public boolean supportsOwnCoordinates() {
return getConnector().supportsOwnCoordinates();
}
- public CacheRealm getCacheRealm() {
- return getConnector().getCacheRealm();
+ public ILoggingManager getLoggingManager(Activity activity) {
+ return getConnector().getLoggingManager(activity, this);
}
@Override
@@ -651,7 +672,7 @@ public class Geocache implements ICache, IWaypoint {
*/
private void initializeCacheTexts() {
if (description == null || shortdesc == null || hint == null || location == null) {
- Geocache partial = cgData.loadCacheTexts(this.getGeocode());
+ final Geocache partial = cgData.loadCacheTexts(this.getGeocode());
if (description == null) {
setDescription(partial.getDescription());
}
@@ -710,10 +731,7 @@ public class Geocache implements ICache, IWaypoint {
public String getPersonalNote() {
// non premium members have no personal notes, premium members have an empty string by default.
// map both to null, so other code doesn't need to differentiate
- if (StringUtils.isBlank(personalNote)) {
- return null;
- }
- return personalNote;
+ return StringUtils.defaultIfBlank(personalNote, null);
}
public boolean supportsUserActions() {
@@ -729,7 +747,7 @@ public class Geocache implements ICache, IWaypoint {
return;
}
- StringBuilder subject = new StringBuilder("Geocache ");
+ final StringBuilder subject = new StringBuilder("Geocache ");
subject.append(geocode);
if (StringUtils.isNotBlank(name)) {
subject.append(" - ").append(name);
@@ -765,13 +783,8 @@ public class Geocache implements ICache, IWaypoint {
return favorite;
}
- public void setFavorite(boolean favourite) {
- this.favorite = favourite;
- }
-
- @Override
- public boolean isWatchlist() {
- return onWatchlist;
+ public void setFavorite(boolean favorite) {
+ this.favorite = favorite;
}
@Override
@@ -829,8 +842,7 @@ public class Geocache implements ICache, IWaypoint {
}
public boolean isVirtual() {
- return CacheType.VIRTUAL == cacheType || CacheType.WEBCAM == cacheType
- || CacheType.EARTH == cacheType;
+ return cacheType.isVirtual();
}
public boolean showSize() {
@@ -922,14 +934,6 @@ public class Geocache implements ICache, IWaypoint {
this.reliableLatLon = reliableLatLon;
}
- public Double getElevation() {
- return elevation;
- }
-
- public void setElevation(Double elevation) {
- this.elevation = elevation;
- }
-
public void setShortDescription(String shortdesc) {
this.shortdesc = shortdesc;
}
@@ -970,6 +974,7 @@ public class Geocache implements ICache, IWaypoint {
this.inventoryItems = inventoryItems;
}
+ @Override
public boolean isOnWatchlist() {
return onWatchlist;
}
@@ -1002,7 +1007,7 @@ public class Geocache implements ICache, IWaypoint {
}
finalDefined = false;
if (waypoints != null) {
- for (Waypoint waypoint : waypoints) {
+ for (final Waypoint waypoint : waypoints) {
waypoint.setGeocode(geocode);
if (waypoint.isFinalWithCoords()) {
finalDefined = true;
@@ -1023,8 +1028,8 @@ public class Geocache implements ICache, IWaypoint {
* @return only the logs of friends, never <code>null</code>
*/
public List<LogEntry> getFriendsLogs() {
- ArrayList<LogEntry> friendLogs = new ArrayList<LogEntry>();
- for (LogEntry log : logs) {
+ final ArrayList<LogEntry> friendLogs = new ArrayList<LogEntry>();
+ for (final LogEntry log : logs) {
if (log.friend) {
friendLogs.add(log);
}
@@ -1117,7 +1122,7 @@ public class Geocache implements ICache, IWaypoint {
}
public void setPersonalNote(String personalNote) {
- this.personalNote = personalNote;
+ this.personalNote = StringUtils.trimToNull(personalNote);
}
public void setDisabled(boolean disabled) {
@@ -1239,7 +1244,7 @@ public class Geocache implements ICache, IWaypoint {
*/
private void resetFinalDefined() {
finalDefined = false;
- for (Waypoint wp : waypoints) {
+ for (final Waypoint wp : waypoints) {
if (wp.isFinalWithCoords()) {
finalDefined = true;
break;
@@ -1360,6 +1365,9 @@ public class Geocache implements ICache, IWaypoint {
return null;
}
+ /**
+ * Detect coordinates in the personal note and convert them to user defined waypoints. Works by rule of thumb.
+ */
public void parseWaypointsFromNote() {
try {
if (StringUtils.isBlank(getPersonalNote())) {
@@ -1378,26 +1386,48 @@ public class Geocache implements ICache, IWaypoint {
((point.getLatitudeE6() % 1000) != 0 || (point.getLongitudeE6() % 1000) != 0) &&
!hasIdenticalWaypoint(point)) {
final String name = cgeoapplication.getInstance().getString(R.string.cache_personal_note) + " " + count;
- final Waypoint waypoint = new Waypoint(name, WaypointType.WAYPOINT, false);
+ final String potentialWaypointType = note.substring(Math.max(0, matcher.start() - 15));
+ final Waypoint waypoint = new Waypoint(name, parseWaypointType(potentialWaypointType), false);
waypoint.setCoords(point);
addOrChangeWaypoint(waypoint, false);
count++;
}
- } catch (Geopoint.ParseException e) {
+ } catch (final Geopoint.ParseException e) {
// ignore
}
note = note.substring(matcher.start() + 1);
matcher = new MatcherWrapper(coordPattern, note);
}
- } catch (Exception e) {
+ } catch (final Exception e) {
Log.e("Geocache.parseWaypointsFromNote", e);
}
}
+ /**
+ * Detect waypoint types in the personal note text. It works by rule of thumb only.
+ */
+ private static WaypointType parseWaypointType(final String input) {
+ final String lowerInput = StringUtils.substring(input, 0, 20).toLowerCase(Locale.getDefault());
+ for (final WaypointType wpType : WaypointType.values()) {
+ if (lowerInput.contains(wpType.getL10n().toLowerCase(Locale.getDefault()))) {
+ return wpType;
+ }
+ if (lowerInput.contains(wpType.id)) {
+ return wpType;
+ }
+ if (lowerInput.contains(wpType.name().toLowerCase(Locale.US))) {
+ return wpType;
+ }
+ }
+ return WaypointType.WAYPOINT;
+ }
+
private boolean hasIdenticalWaypoint(final Geopoint point) {
for (final Waypoint waypoint: waypoints) {
- if (waypoint.getCoords().equals(point)) {
+ // waypoint can have no coords such as a Final set by cache owner
+ final Geopoint coords = waypoint.getCoords();
+ if (coords != null && coords.equals(point)) {
return true;
}
}
@@ -1437,12 +1467,16 @@ public class Geocache implements ICache, IWaypoint {
}
public void store(final int listId, CancellableHandler handler) {
- int newListId = listId < StoredList.STANDARD_LIST_ID
+ final int newListId = listId < StoredList.STANDARD_LIST_ID
? Math.max(getListId(), StoredList.STANDARD_LIST_ID)
: listId;
storeCache(this, null, newListId, false, handler);
}
+ public int getZoomLevel() {
+ return this.zoomlevel;
+ }
+
public void setZoomlevel(int zoomlevel) {
this.zoomlevel = zoomlevel;
}
@@ -1468,7 +1502,7 @@ public class Geocache implements ICache, IWaypoint {
cgData.removeCache(getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE));
handler.sendMessage(Message.obtain());
- } catch (Exception e) {
+ } catch (final Exception e) {
Log.e("cache.drop: ", e);
}
}
@@ -1525,9 +1559,12 @@ public class Geocache implements ICache, IWaypoint {
Geocache cache;
// get cache details, they may not yet be complete
if (origCache != null) {
+ SearchResult search = null;
// only reload the cache if it was already stored or doesn't have full details (by checking the description)
if (origCache.isOffline() || StringUtils.isBlank(origCache.getDescription())) {
- final SearchResult search = searchByGeocode(origCache.getGeocode(), null, listId, false, handler);
+ search = searchByGeocode(origCache.getGeocode(), null, listId, false, handler);
+ }
+ if (search != null) {
cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
} else {
cache = origCache;
@@ -1564,7 +1601,7 @@ public class Geocache implements ICache, IWaypoint {
// store spoilers
if (CollectionUtils.isNotEmpty(cache.getSpoilers())) {
- for (Image oneSpoiler : cache.getSpoilers()) {
+ for (final Image oneSpoiler : cache.getSpoilers()) {
imgGetter.getDrawable(oneSpoiler.getUrl());
}
}
@@ -1575,9 +1612,9 @@ public class Geocache implements ICache, IWaypoint {
// store images from logs
if (Settings.isStoreLogImages()) {
- for (LogEntry log : cache.getLogs()) {
+ for (final LogEntry log : cache.getLogs()) {
if (log.hasLogImages()) {
- for (Image oneLogImg : log.getLogImages()) {
+ for (final Image oneLogImg : log.getLogImages()) {
imgGetter.getDrawable(oneLogImg.getUrl());
}
}
@@ -1600,8 +1637,8 @@ public class Geocache implements ICache, IWaypoint {
if (handler != null) {
handler.sendMessage(Message.obtain());
}
- } catch (Exception e) {
- Log.e("cgBase.storeCache");
+ } catch (final Exception e) {
+ Log.e("Geocache.storeCache", e);
}
}
@@ -1653,7 +1690,7 @@ public class Geocache implements ICache, IWaypoint {
if (hours >= 0 && hours < 24 && minutes >= 0 && minutes < 60) {
return String.valueOf(hours * 60 + minutes);
}
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
// cannot happen, but static code analysis doesn't know
}
}
@@ -1668,7 +1705,7 @@ public class Geocache implements ICache, IWaypoint {
if (hours >= 0 && hours < 24) {
return String.valueOf(hours * 60);
}
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
// cannot happen, but static code analysis doesn't know
}
}
@@ -1697,9 +1734,9 @@ public class Geocache implements ICache, IWaypoint {
}
public List<Image> getImages() {
- List<Image> result = new ArrayList<Image>();
+ final List<Image> result = new ArrayList<Image>();
result.addAll(getSpoilers());
- for (LogEntry log : getLogs()) {
+ for (final LogEntry log : getLogs()) {
result.addAll(log.getLogImages());
}
return result;
@@ -1717,11 +1754,23 @@ public class Geocache implements ICache, IWaypoint {
* the cache, so the result might be wrong.
*/
public boolean hasOwnLog(LogType logType) {
- for (LogEntry logEntry : getLogs()) {
+ for (final LogEntry logEntry : getLogs()) {
if (logEntry.type == logType && logEntry.isOwn()) {
return true;
}
}
return false;
}
+
+ public int getMapMarkerId() {
+ return getConnector().getCacheMapMarkerId(isDisabled() || isArchived());
+ }
+
+ public boolean isLogPasswordRequired() {
+ return logPasswordRequired;
+ }
+
+ public void setLogPasswordRequired(boolean required) {
+ logPasswordRequired = required;
+ }
}