diff options
Diffstat (limited to 'main')
32 files changed, 827 insertions, 817 deletions
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index 3f41f2b..b2d00de 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -974,6 +974,9 @@ <!-- changelog --> <string name="changelog">\n <b>next release</b>\n + · fix: deletion of outdated caches did not work + · fix: changed internal caching causing a better overall performance + · new: login status at start screen · new: changed markers in the map with additional informations for stored caches:\n Personal Note available, Modified coordinates, non-reliable coordinates (orange circle)\n · fix: caches with modified coordinates are displayed at the modified coords and not at the original coords\n diff --git a/main/src/cgeo/geocaching/CacheCache.java b/main/src/cgeo/geocaching/CacheCache.java index 9c02b28..75fcfde 100644 --- a/main/src/cgeo/geocaching/CacheCache.java +++ b/main/src/cgeo/geocaching/CacheCache.java @@ -3,6 +3,8 @@ package cgeo.geocaching; import cgeo.geocaching.cgData.StorageLocation; import cgeo.geocaching.utils.LeastRecentlyUsedCache; +import org.apache.commons.lang3.StringUtils; + /** * Cache for Caches. Every cache is stored in memory while c:geo is active to * speed up the app and to minimize network request - which are slow. @@ -27,7 +29,7 @@ public class CacheCache { return instance; } - public void removeAll() { + public void removeAllFromCache() { cachesCache.clear(); } @@ -36,24 +38,26 @@ public class CacheCache { * Geocode of the cache to remove from the cache */ public void removeCacheFromCache(final String geocode) { - if (geocode != null && cachesCache.containsKey(geocode)) { - cachesCache.remove(geocode); + if (StringUtils.isBlank(geocode)) { + throw new IllegalArgumentException("geocode must not be empty"); } + cachesCache.remove(geocode); } /** + * "Store" a cache in the CacheCache. If the cache is already in the CacheCache the cache gets replaced. + * * @param cache - * Cache to "store" in the cache + * Cache + * */ public void putCacheInCache(final cgCache cache) { - if (cache == null || cache.getGeocode() == null) { - return; + if (cache == null) { + throw new IllegalArgumentException("cache must not be null"); } - - if (cachesCache.containsKey(cache.getGeocode())) { - cachesCache.remove(cache.getGeocode()); + if (StringUtils.isBlank(cache.getGeocode())) { + throw new IllegalArgumentException("geocode must not be empty"); } - cache.addStorageLocation(StorageLocation.CACHE); cachesCache.put(cache.getGeocode(), cache); } @@ -64,11 +68,19 @@ public class CacheCache { * @return cache if found, null else */ public cgCache getCacheFromCache(final String geocode) { - if (geocode != null && cachesCache.containsKey(geocode)) { - return cachesCache.get(geocode); + if (StringUtils.isBlank(geocode)) { + throw new IllegalArgumentException("geocode must not be empty"); } + return cachesCache.get(geocode); + } - return null; + @Override + public String toString() { + String result = ""; + for (String geocode : cachesCache.keySet()) { + result += geocode + " "; + } + return result; } } diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java index 37970b9..eca887f 100644 --- a/main/src/cgeo/geocaching/CacheDetailActivity.java +++ b/main/src/cgeo/geocaching/CacheDetailActivity.java @@ -9,6 +9,8 @@ import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.compatibility.Compatibility; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; +import cgeo.geocaching.enumerations.LoadFlags; +import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.GeopointFormatter; @@ -86,6 +88,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.EnumSet; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -179,7 +182,7 @@ public class CacheDetailActivity extends AbstractActivity { // TODO Why can it happen that search is not null? onCreate should be called only once and it is not set before. if (search != null) { - cache = app.getCache(search); + cache = search.getFirstCacheFromResult(LoadFlags.LOADALLDBONLY); if (cache != null && cache.getGeocode() != null) { geocode = cache.getGeocode(); } @@ -559,8 +562,8 @@ public class CacheDetailActivity extends AbstractActivity { return; } - if (SearchResult.getError(search) != null) { - showToast(res.getString(R.string.err_dwld_details_failed) + " " + SearchResult.getError(search).getErrorString(res) + "."); + if (search.getError() != null) { + showToast(res.getString(R.string.err_dwld_details_failed) + " " + search.getError().getErrorString(res) + "."); finish(); return; @@ -591,7 +594,7 @@ public class CacheDetailActivity extends AbstractActivity { return; } - cache = app.getCache(search); + cache = search.getFirstCacheFromResult(LoadFlags.LOADALLDBONLY); if (cache == null) { progress.dismiss(); @@ -1583,7 +1586,7 @@ public class CacheDetailActivity extends AbstractActivity { storeThread = null; try { - cache = app.getCache(search); // reload cache details + cache = search.getFirstCacheFromResult(LoadFlags.LOADALLDBONLY); // reload cache details } catch (Exception e) { showToast(res.getString(R.string.err_store_failed)); @@ -1610,7 +1613,7 @@ public class CacheDetailActivity extends AbstractActivity { refreshThread = null; try { - cache = app.getCache(search); // reload cache details + cache = search.getFirstCacheFromResult(LoadFlags.LOADALLDBONLY); // reload cache details } catch (Exception e) { showToast(res.getString(R.string.err_refresh_failed)); @@ -1697,7 +1700,7 @@ public class CacheDetailActivity extends AbstractActivity { @Override public void run() { - cgeoapplication.removeCacheFromCache(cache.getGeocode()); + app.removeCache(cache.getGeocode(), EnumSet.of(RemoveFlag.REMOVECACHE)); search = cgBase.searchByGeocode(cache.getGeocode(), null, 0, true, handler); handler.sendEmptyMessage(0); @@ -1728,7 +1731,7 @@ public class CacheDetailActivity extends AbstractActivity { @Override public void run() { - cgBase.dropCache(app, cache, handler); + cgBase.dropCache(cache, handler); } } @@ -1849,7 +1852,7 @@ public class CacheDetailActivity extends AbstractActivity { final Button offlineRefresh = (Button) view.findViewById(R.id.offline_refresh); final Button offlineStore = (Button) view.findViewById(R.id.offline_store); - if (cache.getListId() >= 1) { + if (cache.getListId() >= StoredList.STANDARD_LIST_ID) { long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.getDetailedUpdate() / (60 * 1000)); // minutes String ago = ""; diff --git a/main/src/cgeo/geocaching/ParseResult.java b/main/src/cgeo/geocaching/ParseResult.java deleted file mode 100644 index 180b9c4..0000000 --- a/main/src/cgeo/geocaching/ParseResult.java +++ /dev/null @@ -1,59 +0,0 @@ -package cgeo.geocaching; - -import cgeo.geocaching.enumerations.CacheType; -import cgeo.geocaching.enumerations.LoadFlags; - -import java.util.HashSet; -import java.util.Set; - -/** - * Search result including list of caches - */ -public class ParseResult extends SearchResult { - - public Set<cgCache> cacheList = new HashSet<cgCache>(); - - public ParseResult() { - super(); - } - - public ParseResult(SearchResult searchResult) { - super(searchResult); - } - - public ParseResult(ParseResult parseResult) { - super(parseResult); - cacheList.addAll(parseResult.cacheList); - } - - public ParseResult(final Set<String> geocodes) { - super(geocodes); - cgeoapplication app = cgeoapplication.getInstance(); - for (String geocode : geocodes) { - cacheList.add(app.getCacheByGeocode(geocode, LoadFlags.LOADALL)); - } - } - - public static ParseResult filterParseResults(final ParseResult parseResult, final boolean excludeDisabled, final boolean excludeMine, final CacheType cacheType) { - - ParseResult result = new ParseResult(parseResult); - result.cacheList.clear(); - result.geocodes.clear(); - - if (parseResult != null) { - for (final cgCache cache : parseResult.cacheList) { - // Is there any reason to exclude the cache from the list? - final boolean excludeCache = (excludeDisabled && cache.isDisabled()) || - (excludeMine && (cache.isOwn() || cache.isFound())) || - (cacheType != CacheType.ALL && cacheType != cache.getType()); - if (!excludeCache) { - if (result.addGeocode(cache.getGeocode())) { - result.cacheList.add(cache); - } - } - } - } - - return result; - } -}
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java index fdb50a1..c1e04ef 100644 --- a/main/src/cgeo/geocaching/SearchResult.java +++ b/main/src/cgeo/geocaching/SearchResult.java @@ -1,20 +1,27 @@ package cgeo.geocaching; +import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; +import cgeo.geocaching.enumerations.LoadFlags.LoadFlag; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.StatusCode; +import org.apache.commons.collections.CollectionUtils; + import android.os.Parcel; import android.os.Parcelable; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashSet; import java.util.Set; public class SearchResult implements Parcelable { - final protected Set<String> geocodes; + final private Set<String> geocodes; public StatusCode error = null; - public String url = ""; + private String url = ""; public String[] viewstates = null; public int totalCnt = 0; @@ -94,78 +101,94 @@ public class SearchResult implements Parcelable { return geocodes.size(); } - public boolean addGeocode(final String geocode) { - return geocodes.add(geocode); + public StatusCode getError() { + return error; } - public static StatusCode getError(final SearchResult search) { - if (search == null) { - return null; - } - - return search.error; + public void setError(final StatusCode error) { + this.error = error; } - public static boolean setError(final SearchResult search, final StatusCode error) { - if (search == null) { - return false; - } + public String getUrl() { + return url; + } - search.error = error; + public void setUrl(String url) { + this.url = url; + } - return true; + public String[] getViewstates() { + return viewstates; } - public static String getUrl(final SearchResult search) { - if (search == null) { - return null; + public void setViewstates(String[] viewstates) { + if (cgBase.isEmpty(viewstates)) { + return; } - return search.url; + this.viewstates = viewstates; } - public static boolean setUrl(final SearchResult search, String url) { - if (search == null) { - return false; - } + public int getTotal() { + return totalCnt; + } - search.url = url; + /** + * @param excludeDisabled + * @param excludeMine + * @param cacheType + * @return + */ + public SearchResult filterSearchResults(final boolean excludeDisabled, final boolean excludeMine, final CacheType cacheType, final int listId) { - return true; - } + SearchResult result = new SearchResult(this); + result.geocodes.clear(); - public static String[] getViewstates(final SearchResult search) { - if (search == null) { - return null; + for (final String geocode : geocodes) { + cgCache cache = cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOADCACHEORDB); + // Is there any reason to exclude the cache from the list? + final boolean excludeCache = (excludeDisabled && cache.isDisabled()) || + (excludeMine && (cache.isOwn() || cache.isFound())) || + (cacheType != CacheType.ALL && cacheType != cache.getType()); + if (!excludeCache) { + cache.setListId(listId); + result.addCache(cache); + } } - - return search.viewstates; + return result; } - public static boolean setViewstates(final SearchResult search, String[] viewstates) { - if (cgBase.isEmpty(viewstates) || search == null) { - return false; + public cgCache getFirstCacheFromResult(final EnumSet<LoadFlag> loadFlags) { + if (geocodes != null && geocodes.size() >= 1) { + return cgeoapplication.getInstance().loadCache((String) geocodes.toArray()[0], loadFlags); } + return null; + } - search.viewstates = viewstates; - - return true; + public Set<cgCache> getCachesFromSearchResult(final EnumSet<LoadFlag> loadFlags) { + return cgeoapplication.getInstance().loadCaches(geocodes, loadFlags); } - public static int getTotal(final SearchResult search) { - if (search == null) { - return 0; - } + /** Add the geocode to the search. No cache is loaded into the CacheCache */ + public boolean addGeocode(final String geocode) { + return geocodes.add(geocode); + } - return search.totalCnt; + /** Add the cache geocode to the search and store the cache in the CacheCache */ + public boolean addCache(final cgCache cache) { + addGeocode(cache.getGeocode()); + return cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVECACHE)); } - public static int getCount(final SearchResult search) { - if (search == null) { - return 0; + /** Add the cache geocodes to the search and store them in the CacheCache */ + public void addCaches(final Set<cgCache> caches, final int listId) { + if (CollectionUtils.isEmpty(caches)) { + return; } - return search.getCount(); + for (final cgCache cache : caches) { + cache.setListId(listId); + addCache(cache); + } } - } diff --git a/main/src/cgeo/geocaching/StaticMapsActivity.java b/main/src/cgeo/geocaching/StaticMapsActivity.java index cae01b2..a66b409 100644 --- a/main/src/cgeo/geocaching/StaticMapsActivity.java +++ b/main/src/cgeo/geocaching/StaticMapsActivity.java @@ -1,6 +1,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.enumerations.LoadFlags; import org.apache.commons.collections.CollectionUtils; @@ -85,7 +86,7 @@ public class StaticMapsActivity extends AbstractActivity { dialog.dismiss(); switch (which) { case DialogInterface.BUTTON_POSITIVE: - cgCache cache = app.getCacheByGeocode(geocode); + cgCache cache = app.loadCache(geocode, LoadFlags.LOADCACHEORDB); if (waypoint_id == null) { StaticMapsProvider.storeCacheStaticMap(cache, StaticMapsActivity.this); } else { diff --git a/main/src/cgeo/geocaching/StoredList.java b/main/src/cgeo/geocaching/StoredList.java index 64e2bfd..b88a6bb 100644 --- a/main/src/cgeo/geocaching/StoredList.java +++ b/main/src/cgeo/geocaching/StoredList.java @@ -2,6 +2,7 @@ package cgeo.geocaching; public class StoredList { + public static final int TEMPORARY_LIST_ID = 0; public static final int STANDARD_LIST_ID = 1; public final int id; diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java index 073e347..6ee487a 100644 --- a/main/src/cgeo/geocaching/VisitCacheActivity.java +++ b/main/src/cgeo/geocaching/VisitCacheActivity.java @@ -1,6 +1,9 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.enumerations.LoadFlags; +import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.LogTypeTrackable; import cgeo.geocaching.enumerations.StatusCode; @@ -36,6 +39,7 @@ import android.widget.TextView; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.EnumSet; import java.util.List; public class VisitCacheActivity extends AbstractActivity implements DateDialog.DateDialogParent { @@ -254,7 +258,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D geocode = app.getGeocode(cacheid); } - cache = app.getCacheByGeocode(geocode); + cache = cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOADCACHEORDB); if (StringUtils.isNotBlank(cache.getName())) { setTitle(res.getString(R.string.log_new_log) + ": " + cache.getName()); @@ -688,7 +692,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D public StatusCode postLogFn(String log) { try { - final StatusCode status = cgBase.postLog(app, geocode, cacheid, viewstates, typeSelected, + final StatusCode status = cgBase.postLog(geocode, cacheid, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log, trackables); @@ -711,6 +715,11 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D } } + if (cache != null) { + app.saveCache(cache, EnumSet.of(SaveFlag.SAVECACHE)); + } else { + app.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVECACHE)); + } } if (status == StatusCode.NO_ERROR) { @@ -720,7 +729,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D if (status == StatusCode.NO_ERROR && typeSelected == LogType.LOG_FOUND_IT && Settings.isUseTwitter() && Settings.isTwitterLoginValid() && tweetCheck.isChecked() && tweetBox.getVisibility() == View.VISIBLE) { - cgBase.postTweetCache(app, geocode); + cgBase.postTweetCache(geocode); } if (status == StatusCode.NO_ERROR && typeSelected == LogType.LOG_FOUND_IT && Settings.isGCvoteLogin()) { diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java index e75808f..ea90e5d 100644 --- a/main/src/cgeo/geocaching/cgBase.java +++ b/main/src/cgeo/geocaching/cgBase.java @@ -6,6 +6,9 @@ import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.GCConnector; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; +import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.LogTypeTrackable; import cgeo.geocaching.enumerations.StatusCode; @@ -88,12 +91,12 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; +import java.util.EnumSet; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; import java.util.regex.Matcher; import javax.net.ssl.HostnameVerifier; @@ -117,8 +120,7 @@ public class cgBase { Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>(); - for (String format : formats) - { + for (String format : formats) { map.put(format, new SimpleDateFormat(format, Locale.ENGLISH)); } @@ -436,7 +438,7 @@ public class cgBase { } } - private static ParseResult parseSearch(final cgSearchThread thread, final String url, final String pageContent, final boolean showCaptcha) { + private static SearchResult parseSearch(final cgSearchThread thread, final String url, final String pageContent, final boolean showCaptcha, final int listId) { if (StringUtils.isBlank(pageContent)) { Log.e(Settings.tag, "cgeoBase.parseSearch: No page given"); return null; @@ -448,9 +450,9 @@ public class cgBase { String recaptchaText = null; String page = pageContent; - final ParseResult parseResult = new ParseResult(); - parseResult.url = url; - parseResult.viewstates = getViewstates(page); + final SearchResult searchResult = new SearchResult(); + searchResult.setUrl(url); + searchResult.viewstates = getViewstates(page); // recaptcha if (showCaptcha) { @@ -472,7 +474,7 @@ public class cgBase { if (!page.contains("SearchResultsTable")) { // there are no results. aborting here avoids a wrong error log in the next parsing step - return parseResult; + return searchResult; } int startPos = page.indexOf("<div id=\"ctl00_ContentBody_ResultsPanel\""); @@ -497,6 +499,7 @@ public class cgBase { for (int z = 1; z < rows_count; z++) { cgCache cache = new cgCache(); + cache.setListId(listId); String row = rows[z]; // check for cache type presence @@ -610,14 +613,14 @@ public class cgBase { // location is reliable because the search return correct coords independant of the login status cache.setReliableLatLon(true); - parseResult.cacheList.add(cache); + searchResult.addCache(cache); } // total caches found try { String result = BaseUtils.getMatch(page, GCConstants.PATTERN_SEARCH_TOTALCOUNT, false, 1, null, true); if (null != result) { - parseResult.totalCnt = Integer.parseInt(result); + searchResult.totalCnt = Integer.parseInt(result); } } catch (NumberFormatException e) { Log.w(Settings.tag, "cgeoBase.parseSearch: Failed to parse cache count"); @@ -639,13 +642,13 @@ public class cgBase { final Parameters params = new Parameters( "__EVENTTARGET", "", "__EVENTARGUMENT", ""); - if (ArrayUtils.isNotEmpty(parseResult.viewstates)) { - params.put("__VIEWSTATE", parseResult.viewstates[0]); - if (parseResult.viewstates.length > 1) { - for (int i = 1; i < parseResult.viewstates.length; i++) { - params.put("__VIEWSTATE" + i, parseResult.viewstates[i]); + if (ArrayUtils.isNotEmpty(searchResult.viewstates)) { + params.put("__VIEWSTATE", searchResult.viewstates[0]); + if (searchResult.viewstates.length > 1) { + for (int i = 1; i < searchResult.viewstates.length; i++) { + params.put("__VIEWSTATE" + i, searchResult.viewstates[i]); } - params.put("__VIEWSTATEFIELDCOUNT", "" + parseResult.viewstates.length); + params.put("__VIEWSTATEFIELDCOUNT", "" + searchResult.viewstates.length); } } for (String cid : cids) { @@ -664,13 +667,13 @@ public class cgBase { if (coordinates.contains("You have not agreed to the license agreement. The license agreement is required before you can start downloading GPX or LOC files from Geocaching.com")) { Log.i(Settings.tag, "User has not agreed to the license agreement. Can\'t download .loc file."); - parseResult.error = StatusCode.UNAPPROVED_LICENSE; + searchResult.error = StatusCode.UNAPPROVED_LICENSE; - return parseResult; + return searchResult; } } - LocParser.parseLoc(parseResult, coordinates); + LocParser.parseLoc(searchResult, coordinates); } catch (Exception e) { Log.e(Settings.tag, "cgBase.parseSearch.CIDs: " + e.toString()); } @@ -679,7 +682,8 @@ public class cgBase { // get direction images if (Settings.getLoadDirImg()) { - for (cgCache oneCache : parseResult.cacheList) { + for (String geocode : searchResult.getGeocodes()) { + cgCache oneCache = cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOADCACHEORDB); if (oneCache.getCoords() == null && StringUtils.isNotEmpty(oneCache.getDirectionImg())) { DirectionImage.getDrawable(oneCache.getGeocode(), oneCache.getDirectionImg()); } @@ -696,7 +700,8 @@ public class cgBase { if (MapUtils.isNotEmpty(ratings)) { // save found cache coordinates - for (cgCache cache : parseResult.cacheList) { + for (String geocode : searchResult.getGeocodes()) { + cgCache cache = cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOADCACHEORDB); if (ratings.containsKey(cache.getGuid())) { GCVoteRating rating = ratings.get(cache.getGuid()); @@ -712,17 +717,17 @@ public class cgBase { } } - return parseResult; + return searchResult; } - public static ParseResult parseMapJSON(final String uri, final String data) { + public static SearchResult parseMapJSON(final String uri, final String data) { if (StringUtils.isEmpty(data)) { Log.e(Settings.tag, "cgeoBase.parseMapJSON: No page given"); return null; } - final ParseResult parseResult = new ParseResult(); - parseResult.url = uri; + final SearchResult searchResult = new SearchResult(); + searchResult.setUrl(uri); try { final JSONObject yoDawg = new JSONObject(data); @@ -741,7 +746,7 @@ public class cgBase { // check login status boolean li = extra.getBoolean("li"); if (!li) { - parseResult.error = StatusCode.NOT_LOGGED_IN; + searchResult.error = StatusCode.NOT_LOGGED_IN; } if (count > 0 && extra.has("cc")) { @@ -793,37 +798,41 @@ public class cgBase { cacheToAdd.setType(CacheType.UNKNOWN); } - parseResult.cacheList.add(cacheToAdd); + searchResult.addCache(cacheToAdd); } } } else { - Log.w(Settings.tag, "There are no caches in viewport"); + Log.w(Settings.tag, "There are no caches in viewport. Probably the viewport is to big"); } - parseResult.totalCnt = parseResult.cacheList.size(); + searchResult.totalCnt = searchResult.getGeocodes().size(); } } catch (Exception e) { Log.e(Settings.tag, "cgBase.parseMapJSON", e); } - return parseResult; + return searchResult; } - public static ParseResult parseCache(final String page, final int listId, final CancellableHandler handler) { - final ParseResult parseResult = parseCacheFromText(page, listId, handler); - if (parseResult != null && !parseResult.cacheList.isEmpty()) { - final cgCache cache = cgBase.getFirstElementFromSet(parseResult.cacheList); + public static SearchResult parseCache(final String page, final int listId, final CancellableHandler handler) { + final SearchResult searchResult = parseCacheFromText(page, listId, handler); + if (searchResult != null && !searchResult.getGeocodes().isEmpty()) { + final cgCache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOADCACHEORDB); getExtraOnlineInfo(cache, page, handler); cache.setUpdated(System.currentTimeMillis()); cache.setDetailedUpdate(cache.getUpdated()); cache.setDetailed(true); + if (CancellableHandler.isCancelled(handler)) { + return null; + } + // save full detailed caches + sendLoadProgressDetail(handler, R.string.cache_dialog_offline_save_message); + cache.setListId(StoredList.TEMPORARY_LIST_ID); + cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVEDB)); } - if (CancellableHandler.isCancelled(handler)) { - return null; - } - return parseResult; + return searchResult; } - static ParseResult parseCacheFromText(final String page, final int listId, final CancellableHandler handler) { + static SearchResult parseCacheFromText(final String page, final int listId, final CancellableHandler handler) { sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details); if (StringUtils.isBlank(page)) { @@ -831,21 +840,21 @@ public class cgBase { return null; } - final ParseResult parseResult = new ParseResult(); + final SearchResult searchResult = new SearchResult(); if (page.contains("Cache is Unpublished")) { - parseResult.error = StatusCode.UNPUBLISHED_CACHE; - return parseResult; + searchResult.error = StatusCode.UNPUBLISHED_CACHE; + return searchResult; } if (page.contains("Sorry, the owner of this listing has made it viewable to Premium Members only.")) { - parseResult.error = StatusCode.PREMIUM_ONLY; - return parseResult; + searchResult.error = StatusCode.PREMIUM_ONLY; + return searchResult; } if (page.contains("has chosen to make this cache listing visible to Premium Members only.")) { - parseResult.error = StatusCode.PREMIUM_ONLY; - return parseResult; + searchResult.error = StatusCode.PREMIUM_ONLY; + return searchResult; } final cgCache cache = new cgCache(); @@ -1112,8 +1121,8 @@ public class cgBase { final String originalCoords = BaseUtils.getMatch(page, GCConstants.PATTERN_LATLON_ORIG, false, null); if (null != originalCoords) { - // res = null in unit tests - final cgWaypoint waypoint = new cgWaypoint(res != null ? res.getString(R.string.cache_coordinates_original) : "", WaypointType.WAYPOINT); + // res is null during the unit tests + final cgWaypoint waypoint = new cgWaypoint(res != null ? res.getString(R.string.cache_coordinates_original) : "res = null", WaypointType.WAYPOINT); waypoint.setCoords(new Geopoint(originalCoords)); cache.addWaypoint(waypoint); cache.setUserModifiedCoords(true); @@ -1157,8 +1166,8 @@ public class cgBase { wp = wpItems[j].split("<td"); // waypoint name - // res = null in unit tests - final String name = BaseUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, res != null ? res.getString(R.string.waypoint) : null, true); + // res is null during the unit tests + final String name = BaseUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, res != null ? res.getString(R.string.waypoint) : "res = null", true); // waypoint type final String resulttype = BaseUtils.getMatch(wp[3], GCConstants.PATTERN_WPTYPE, null); @@ -1196,8 +1205,8 @@ public class cgBase { // logs cache.setLogs(loadLogsFromDetails(page, cache, false, true)); - parseResult.cacheList.add(cache); - return parseResult; + searchResult.addCache(cache); + return searchResult; } private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) { @@ -1465,7 +1474,7 @@ public class cgBase { * if not null, the application to use to save the trackable * @return the parsed trackable, or null if none could be parsed */ - public static cgTrackable parseTrackable(final String page, final cgeoapplication app, final String possibleTrackingcode) { + public static cgTrackable parseTrackable(final String page, cgeoapplication app, final String possibleTrackingcode) { if (StringUtils.isBlank(page)) { Log.e(Settings.tag, "cgeoBase.parseTrackable: No page given"); return null; @@ -1768,10 +1777,13 @@ public class cgBase { params.put("tx", cacheType.guid); } - public static ParseResult searchByNextPage(cgSearchThread thread, final ParseResult search, int listId, boolean showCaptcha) { - final String[] viewstates = SearchResult.getViewstates(search); + public static SearchResult searchByNextPage(cgSearchThread thread, final SearchResult search, int listId, boolean showCaptcha) { + if (search == null) { + return search; + } + final String[] viewstates = search.getViewstates(); - final String url = SearchResult.getUrl(search); + final String url = search.getUrl(); if (StringUtils.isBlank(url)) { Log.e(Settings.tag, "cgeoBase.searchByNextPage: No url found"); @@ -1799,7 +1811,7 @@ public class cgBase { } else if (loginState == StatusCode.NO_LOGIN_INFO_STORED) { Log.i(Settings.tag, "Working as guest."); } else { - SearchResult.setError(search, loginState); + search.setError(loginState); Log.e(Settings.tag, "cgeoBase.searchByNextPage: Can not log in geocaching"); return search; } @@ -1810,37 +1822,30 @@ public class cgBase { return search; } - final ParseResult parseResult = parseSearch(thread, url, page, showCaptcha); - if (parseResult == null || CollectionUtils.isEmpty(parseResult.cacheList)) { + final SearchResult searchResult = parseSearch(thread, url, page, showCaptcha, listId); + if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) { Log.e(Settings.tag, "cgeoBase.searchByNextPage: No cache parsed"); return search; } // save to application - SearchResult.setError(search, parseResult.error); - SearchResult.setViewstates(search, parseResult.viewstates); - if (search != null) { - search.cacheList = parseResult.cacheList; - - for (final cgCache cache : parseResult.cacheList) { - search.addGeocode(cache.getGeocode()); - } + search.setError(searchResult.error); + search.setViewstates(searchResult.viewstates); + for (String geocode : searchResult.getGeocodes()) { + search.addGeocode(geocode); } - - cgeoapplication.getInstance().addSearch(parseResult.cacheList, listId); - return search; } - public static ParseResult searchByGeocode(final String geocode, final String guid, final int listId, final boolean forceReload, final CancellableHandler handler) { + public static SearchResult searchByGeocode(final String geocode, final String guid, final int listId, final boolean forceReload, final CancellableHandler handler) { if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { Log.e(Settings.tag, "cgeoBase.searchByGeocode: No geocode nor guid given"); return null; } cgeoapplication app = cgeoapplication.getInstance(); - if (!forceReload && listId == 0 && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) { - final ParseResult search = new ParseResult(); + if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) { + final SearchResult search = new SearchResult(); final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : app.getGeocode(guid); search.addGeocode(realGeocode); return search; @@ -1854,7 +1859,7 @@ public class cgBase { return ConnectorFactory.getConnector(geocode).searchByGeocode(geocode, guid, app, listId, handler); } - public static SearchResult searchByOffline(final Geopoint coords, final CacheType cacheType, final int list) { + public static SearchResult searchByStored(final Geopoint coords, final CacheType cacheType, final int list) { return cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, cacheType, list); } @@ -1868,7 +1873,7 @@ public class cgBase { * the parameters to add to the request URI * @return */ - private static ParseResult searchByAny(final cgSearchThread thread, final CacheType cacheType, final boolean my, final int listId, final boolean showCaptcha, final Parameters params) { + private static SearchResult searchByAny(final cgSearchThread thread, final CacheType cacheType, final boolean my, final int listId, final boolean showCaptcha, final Parameters params) { insertCacheType(params, cacheType); final String uri = "http://www.geocaching.com/seek/nearest.aspx"; @@ -1880,26 +1885,25 @@ public class cgBase { return null; } - final ParseResult parseResult = parseSearch(thread, fullUri, page, showCaptcha); - if (parseResult == null || CollectionUtils.isEmpty(parseResult.cacheList)) { + final SearchResult searchResult = parseSearch(thread, fullUri, page, showCaptcha, listId); + if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) { Log.e(Settings.tag, "cgeoBase.searchByAny: No cache parsed"); - return parseResult; + return searchResult; } - final ParseResult search = ParseResult.filterParseResults(parseResult, Settings.isExcludeDisabledCaches(), false, cacheType); - cgeoapplication.getInstance().addSearch(search.cacheList, listId); + final SearchResult search = searchResult.filterSearchResults(Settings.isExcludeDisabledCaches(), false, cacheType, listId); getLoginStatus(page); return search; } - public static ParseResult searchByCoords(final cgSearchThread thread, final Geopoint coords, final CacheType cacheType, final int listId, final boolean showCaptcha) { + public static SearchResult searchByCoords(final cgSearchThread thread, final Geopoint coords, final CacheType cacheType, final int listId, final boolean showCaptcha) { final Parameters params = new Parameters("lat", Double.toString(coords.getLatitude()), "lng", Double.toString(coords.getLongitude())); return searchByAny(thread, cacheType, false, listId, showCaptcha, params); } - public static ParseResult searchByKeyword(final cgSearchThread thread, final String keyword, final CacheType cacheType, final int listId, final boolean showCaptcha) { + public static SearchResult searchByKeyword(final cgSearchThread thread, final String keyword, final CacheType cacheType, final int listId, final boolean showCaptcha) { if (StringUtils.isBlank(keyword)) { Log.e(Settings.tag, "cgeoBase.searchByKeyword: No keyword given"); return null; @@ -1909,7 +1913,7 @@ public class cgBase { return searchByAny(thread, cacheType, false, listId, showCaptcha, params); } - public static ParseResult searchByUsername(final cgSearchThread thread, final String userName, final CacheType cacheType, final int listId, final boolean showCaptcha) { + public static SearchResult searchByUsername(final cgSearchThread thread, final String userName, final CacheType cacheType, final int listId, final boolean showCaptcha) { if (StringUtils.isBlank(userName)) { Log.e(Settings.tag, "cgeoBase.searchByUsername: No user name given"); return null; @@ -1926,7 +1930,7 @@ public class cgBase { return searchByAny(thread, cacheType, my, listId, showCaptcha, params); } - public static ParseResult searchByOwner(final cgSearchThread thread, final String userName, final CacheType cacheType, final int listId, final boolean showCaptcha) { + public static SearchResult searchByOwner(final cgSearchThread thread, final String userName, final CacheType cacheType, final int listId, final boolean showCaptcha) { if (StringUtils.isBlank(userName)) { Log.e(Settings.tag, "cgeoBase.searchByOwner: No user name given"); return null; @@ -1936,7 +1940,7 @@ public class cgBase { return searchByAny(thread, cacheType, false, listId, showCaptcha, params); } - public static ParseResult searchByViewport(final String userToken, final Viewport viewport) { + public static SearchResult searchByViewport(final String userToken, final Viewport viewport) { String page = null; @@ -1953,15 +1957,13 @@ public class cgBase { return null; } - final ParseResult parseResult = parseMapJSON(Uri.parse(uri).buildUpon().encodedQuery(params).build().toString(), page); - if (parseResult == null || CollectionUtils.isEmpty(parseResult.cacheList)) { + final SearchResult searchResult = parseMapJSON(Uri.parse(uri).buildUpon().encodedQuery(params).build().toString(), page); + if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) { Log.e(Settings.tag, "cgeoBase.searchByViewport: No cache parsed"); return null; } - final ParseResult search = ParseResult.filterParseResults(parseResult, Settings.isExcludeDisabledCaches(), Settings.isExcludeMyCaches(), Settings.getCacheType()); - cgeoapplication.getInstance().addSearch(search.cacheList, 0); - + final SearchResult search = searchResult.filterSearchResults(Settings.isExcludeDisabledCaches(), Settings.isExcludeMyCaches(), Settings.getCacheType(), StoredList.TEMPORARY_LIST_ID); return search; } @@ -2016,7 +2018,7 @@ public class cgBase { return trackable; } - public static StatusCode postLog(final cgeoapplication app, final String geocode, final String cacheid, final String[] viewstates, + public static StatusCode postLog(final String geocode, final String cacheid, final String[] viewstates, final LogType logType, final int year, final int month, final int day, final String log, final List<cgTrackableLog> trackables) { if (isEmpty(viewstates)) { @@ -2155,8 +2157,8 @@ public class cgBase { if (matcherOk.find()) { Log.i(Settings.tag, "Log successfully posted to cache #" + cacheid); - if (app != null && geocode != null) { - app.saveVisitDate(geocode); + if (geocode != null) { + cgeoapplication.getInstance().saveVisitDate(geocode); } getLoginStatus(page); @@ -2310,8 +2312,8 @@ public class cgBase { } }; - public static void postTweetCache(cgeoapplication app, String geocode) { - final cgCache cache = app.getCacheByGeocode(geocode); + public static void postTweetCache(String geocode) { + final cgCache cache = cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOADCACHEORDB); String status; final String url = cache.getUrl(); if (url.length() >= 100) { @@ -2328,11 +2330,11 @@ public class cgBase { status = Twitter.appendHashTag(status, "geocaching"); } - Twitter.postTweet(app, status, null); + Twitter.postTweet(cgeoapplication.getInstance(), status, null); } - public static void postTweetTrackable(cgeoapplication app, String geocode) { - final cgTrackable trackable = app.getTrackableByGeocode(geocode); + public static void postTweetTrackable(String geocode) { + final cgTrackable trackable = cgeoapplication.getInstance().getTrackableByGeocode(geocode); String name = trackable.getName(); if (name.length() > 82) { name = name.substring(0, 79) + "..."; @@ -2345,7 +2347,7 @@ public class cgBase { builder.append('!'); String status = Twitter.appendHashTag(builder.toString(), "cgeo"); status = Twitter.appendHashTag(status, "geocaching"); - Twitter.postTweet(app, status, null); + Twitter.postTweet(cgeoapplication.getInstance(), status, null); } public static String getLocalIpAddress() { @@ -2655,20 +2657,19 @@ public class cgBase { public static void storeCache(Activity activity, cgCache origCache, String geocode, int listId, CancellableHandler handler) { try { - cgeoapplication app = cgeoapplication.getInstance(); cgCache cache; // get cache details, they may not yet be complete if (origCache != null) { // only reload the cache, if it was already stored or has not all details (by checking the description) - if (origCache.getListId() > 0 || StringUtils.isBlank(origCache.getDescription())) { + if (origCache.getListId() >= StoredList.STANDARD_LIST_ID || StringUtils.isBlank(origCache.getDescription())) { final SearchResult search = searchByGeocode(origCache.getGeocode(), null, listId, false, null); - cache = app.getCache(search); + cache = search.getFirstCacheFromResult(LoadFlags.LOADCACHEORDB); } else { cache = origCache; } } else if (StringUtils.isNotBlank(geocode)) { final SearchResult search = searchByGeocode(geocode, null, listId, false, null); - cache = app.getCache(search); + cache = search.getFirstCacheFromResult(LoadFlags.LOADCACHEORDB); } else { cache = null; } @@ -2729,8 +2730,8 @@ public class cgBase { return; } - app.markStored(cache.getGeocode(), listId); - cgeoapplication.removeCacheFromCache(cache.getGeocode()); + cache.setListId(listId); + cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVEDB)); if (handler != null) { handler.sendMessage(new Message()); @@ -2740,10 +2741,10 @@ public class cgBase { } } - public static void dropCache(final cgeoapplication app, final cgCache cache, final Handler handler) { + public static void dropCache(final cgCache cache, final Handler handler) { try { - app.markDropped(cache.getGeocode()); - cgeoapplication.removeCacheFromCache(cache.getGeocode()); + cgeoapplication.getInstance().markDropped(cache.getGeocode()); + cgeoapplication.getInstance().removeCache(cache.getGeocode(), EnumSet.of(RemoveFlag.REMOVECACHE)); handler.sendMessage(new Message()); } catch (Exception e) { @@ -3112,14 +3113,6 @@ public class cgBase { return starsContainer; } - @SuppressWarnings("unchecked") - public static <T> T getFirstElementFromSet(Set<T> set) { - if (set != null && set.size() >= 1) { - return ((T[]) set.toArray())[0]; - } - return null; - } - public static boolean isActualLoginStatus() { return actualLoginStatus; } diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/cgCache.java index 9fdaaaf..8b4e6ef 100644 --- a/main/src/cgeo/geocaching/cgCache.java +++ b/main/src/cgeo/geocaching/cgCache.java @@ -7,6 +7,7 @@ import cgeo.geocaching.connector.GCConnector; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; @@ -45,7 +46,7 @@ public class cgCache implements ICache { private long updated = 0; private long detailedUpdate = 0; private long visitedDate = 0; - private int listId = 0; + private int listId = StoredList.TEMPORARY_LIST_ID; private boolean detailed = false; private String geocode = ""; private String cacheId = ""; @@ -136,7 +137,7 @@ public class cgCache implements ICache { if (visitedDate == 0) { visitedDate = other.getVisitedDate(); } - if (listId == 0) { + if (listId == StoredList.TEMPORARY_LIST_ID) { listId = other.listId; } if (StringUtils.isBlank(geocode)) { @@ -1146,7 +1147,7 @@ public class cgCache implements ICache { if (waypoint.isUserDefined()) { waypoints.remove(index); cgeoapplication.getInstance().deleteWaypoint(waypoint.getId()); - cgeoapplication.removeCacheFromCache(geocode); + cgeoapplication.getInstance().removeCache(geocode, EnumSet.of(RemoveFlag.REMOVECACHE)); return true; } return false; @@ -1260,7 +1261,8 @@ public class cgCache implements ICache { if (getClass() != obj.getClass()) { return false; } - return isEqualTo((cgCache) obj); + // just compare the geocode even if that is not what "equals" normaly does + return geocode != null ? geocode.compareTo(((cgCache) obj).geocode) == 0 : false; } public void store(Activity activity, CancellableHandler handler) { diff --git a/main/src/cgeo/geocaching/cgData.java b/main/src/cgeo/geocaching/cgData.java index 0852e43..f23b794 100644 --- a/main/src/cgeo/geocaching/cgData.java +++ b/main/src/cgeo/geocaching/cgData.java @@ -2,7 +2,10 @@ package cgeo.geocaching; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.LoadFlag; +import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.files.LocalStorage; @@ -59,6 +62,7 @@ public class cgData { */ private static int[] cacheColumnIndex; private Context context = null; + private CacheCache cacheCache = null; private String path = null; private cgDbHelper dbHelper = null; private SQLiteDatabase databaseRO = null; @@ -240,6 +244,7 @@ public class cgData { public cgData(Context contextIn) { context = contextIn; + cacheCache = CacheCache.getInstance(); } public synchronized void init() { @@ -297,6 +302,9 @@ public class cgData { } public void closeDb() { + + cacheCache.removeAllFromCache(); + initialized = false; closePreparedStatements(); @@ -1110,11 +1118,13 @@ public class cgData { return false; } + /** Cache stored in DB with listId >= 1 */ + // TODO Simply like getCacheDescription() public boolean isOffline(String geocode, String guid) { init(); Cursor cursor = null; - long listId = 0; + long listId = StoredList.TEMPORARY_LIST_ID; try { if (StringUtils.isNotBlank(geocode)) { @@ -1158,112 +1168,88 @@ public class cgData { Log.e(Settings.tag, "cgData.isOffline: " + e.toString()); } - return listId >= 1; + return listId >= StoredList.STANDARD_LIST_ID; } public String getGeocodeForGuid(String guid) { if (StringUtils.isBlank(guid)) { return null; } - init(); - Cursor cursor = null; - String geocode = null; - try { - cursor = databaseRO.query( - dbTableCaches, - new String[] { "geocode" }, - "guid = ?", - new String[] { guid }, - null, - null, - null, - "1"); - - if (cursor != null) { - int index = 0; - - if (cursor.getCount() > 0) { - cursor.moveToFirst(); - - index = cursor.getColumnIndex("geocode"); - geocode = cursor.getString(index); - } + final SQLiteStatement description = getStatementGeocode(); + synchronized (description) { + description.bindString(1, guid); + return description.simpleQueryForString(); } + } catch (SQLiteDoneException e) { + // Do nothing, it only means we have no information on the cache } catch (Exception e) { - Log.e(Settings.tag, "cgData.getGeocodeForGuid: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); + Log.e(Settings.tag, "cgData.getGeocodeForGuid", e); } - return geocode; + return null; } public String getCacheidForGeocode(String geocode) { if (StringUtils.isBlank(geocode)) { return null; } - init(); - Cursor cursor = null; - String cacheid = null; - try { - cursor = databaseRO.query( - dbTableCaches, - new String[] { "cacheid" }, - "geocode = ?", - new String[] { geocode }, - null, - null, - null, - "1"); - - if (cursor != null) { - int index = 0; - - if (cursor.getCount() > 0) { - cursor.moveToFirst(); - - index = cursor.getColumnIndex("cacheid"); - cacheid = cursor.getString(index); - } + final SQLiteStatement description = getStatementCacheId(); + synchronized (description) { + description.bindString(1, geocode); + return description.simpleQueryForString(); } + } catch (SQLiteDoneException e) { + // Do nothing, it only means we have no information on the cache } catch (Exception e) { - Log.e(Settings.tag, "cgData.getCacheidForGeocode: " + e.toString()); - } - - if (cursor != null) { - cursor.close(); + Log.e(Settings.tag, "cgData.getCacheidForGeocode", e); } - return cacheid; + return null; } /** + * Save/store a cache to the CacheCache + * * @param cache - * @return true = cache saved successfully to the DB + * the Cache to save in the CacheCache/DB + * @param saveFlag + * + * @return true = cache saved successfully to the CacheCache/DB */ - public boolean saveCache(cgCache cache) { - //LeeB - writing to the DB is slow + public boolean saveCache(cgCache cache, EnumSet<LoadFlags.SaveFlag> saveFlags) { if (cache == null) { - return false; + throw new IllegalArgumentException("cache must not be null"); } - // remember this cache in the caches cache. it is highly likely that we will need it in a few moments and - // this way we also remove any stale instance from the caches cache - cgeoapplication.putCacheInCache(cache); + // merge always with data already stored in the CacheCache or DB + if (saveFlags.contains(SaveFlag.SAVECACHE)) { + cache.gatherMissingFrom(cacheCache.getCacheFromCache(cache.getGeocode())); + cacheCache.putCacheInCache(cache); + } + + if (!saveFlags.contains(SaveFlag.SAVEDB)) { + return true; + } + boolean updateRequired = !cache.gatherMissingFrom(loadCache(cache.getGeocode(), LoadFlags.LOADALLDBONLY)); - // only save fully detailed caches in the database - if (!cache.isDetailed()) { + // only save a cache to the database if + // - the cache is detailed + // - there are changes + // - the cache is only stored in the CacheCache so far + if ((!updateRequired || !cache.isDetailed()) && cache.getStorageLocation().contains(StorageLocation.DATABASE)) { return false; } + cache.addStorageLocation(StorageLocation.DATABASE); + cacheCache.putCacheInCache(cache); + Log.d(Settings.tag, "Saving " + cache.toString() + " (" + cache.getListId() + ") to DB"); + ContentValues values = new ContentValues(); if (cache.getUpdated() == 0) { @@ -1361,38 +1347,33 @@ public class cgData { init(); //try to update record else insert fresh.. + boolean result = false; + databaseRW.beginTransaction(); try { int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { cache.getGeocode() }); - if (rows > 0) { - values = null; - return true; - } - } catch (Exception e) { - // nothing - } - - try { - long id = databaseRW.insert(dbTableCaches, null, values); - if (id > 0) { - values = null; - return true; + if (rows == 0) { + // cache is not in the DB, insert it + /* long id = */databaseRW.insert(dbTableCaches, null, values); } + databaseRW.setTransactionSuccessful(); + result = true; } catch (Exception e) { // nothing + } finally { + databaseRW.endTransaction(); } values = null; - - return false; + return result; } public boolean saveAttributes(String geocode, List<String> attributes) { - init(); - if (StringUtils.isBlank(geocode) || attributes == null) { return false; } + init(); + databaseRW.beginTransaction(); try { databaseRW.delete(dbTableAttributes, "geocode = ?", new String[] { geocode }); @@ -1458,12 +1439,12 @@ public class cgData { } public boolean saveWaypoints(String geocode, List<cgWaypoint> waypoints, boolean drop) { - init(); - if (StringUtils.isBlank(geocode) || waypoints == null) { return false; } + init(); + Log.d(Settings.tag, "cgData.saveWaypoints(drop=" + drop + ")"); boolean ok = false; @@ -1539,12 +1520,12 @@ public class cgData { } public boolean saveOwnWaypoint(int id, String geocode, cgWaypoint waypoint) { - init(); - if ((StringUtils.isBlank(geocode) && id <= 0) || waypoint == null) { return false; } + init(); + boolean ok = false; databaseRW.beginTransaction(); try { @@ -1580,12 +1561,12 @@ public class cgData { } public boolean deleteWaypoint(int id) { - init(); - if (id == 0) { return false; } + init(); + int deleted = databaseRW.delete(dbTableWaypoints, "_id = " + id, null); if (deleted > 0) { @@ -1596,12 +1577,12 @@ public class cgData { } public boolean saveSpoilers(String geocode, List<cgImage> spoilers) { - init(); - if (StringUtils.isBlank(geocode) || spoilers == null) { return false; } + init(); + databaseRW.beginTransaction(); try { databaseRW.delete(dbTableSpoilers, "geocode = ?", new String[] { geocode }); @@ -1633,12 +1614,12 @@ public class cgData { } public boolean saveLogs(String geocode, List<cgLog> logs, boolean drop) { - init(); - if (StringUtils.isBlank(geocode) || logs == null) { return false; } + init(); + databaseRW.beginTransaction(); try { if (drop) { @@ -1689,12 +1670,12 @@ public class cgData { } public boolean saveLogCount(String geocode, Map<LogType, Integer> logCounts, boolean drop) { - init(); - if (StringUtils.isBlank(geocode) || MapUtils.isEmpty(logCounts)) { return false; } + init(); + databaseRW.beginTransaction(); try { if (drop) { @@ -1723,12 +1704,12 @@ public class cgData { } public boolean saveInventory(String geocode, List<cgTrackable> trackables) { - init(); - if (trackables == null) { return false; } + init(); + databaseRW.beginTransaction(); try { if (geocode != null) { @@ -1769,153 +1750,146 @@ public class cgData { return true; } - public List<Number> getBounds(Object[] geocodes) { - init(); - - Cursor cursor = null; - - final List<Number> viewport = new ArrayList<Number>(); - - try { - final StringBuilder where = new StringBuilder(); - - if (geocodes != null && geocodes.length > 0) { - StringBuilder all = new StringBuilder(); - for (Object one : geocodes) { - if (all.length() > 0) { - all.append(", "); - } - all.append('"'); - all.append((String) one); - all.append('"'); - } - - if (where.length() > 0) { - where.append(" and "); - } - where.append("geocode in ("); - where.append(all); - where.append(')'); - } - - cursor = databaseRO.query( - dbTableCaches, - new String[] { "count(_id) as cnt", "min(latitude) as latMin", "max(latitude) as latMax", "min(longitude) as lonMin", "max(longitude) as lonMax" }, - where.toString(), - null, - null, - null, - null, - null); - - if (cursor != null) { - int cnt = cursor.getCount(); - - if (cnt > 0) { - cursor.moveToFirst(); - - viewport.add(cursor.getInt(cursor.getColumnIndex("cnt"))); - viewport.add(cursor.getDouble(cursor.getColumnIndex("latMin"))); - viewport.add(cursor.getDouble(cursor.getColumnIndex("latMax"))); - viewport.add(cursor.getDouble(cursor.getColumnIndex("lonMin"))); - viewport.add(cursor.getDouble(cursor.getColumnIndex("lonMax"))); - } - } - } catch (Exception e) { - Log.e(Settings.tag, "cgData.getBounds: " + e.toString()); + public List<Number> getBounds(Set<String> geocodes) { + if (CollectionUtils.isEmpty(geocodes)) { + return null; } - if (cursor != null) { - cursor.close(); + Set<cgCache> caches = loadCaches(geocodes, LoadFlags.LOADCACHEORDB); + + Double latMin = 360.0; + Double latMax = 0.0; + Double lonMin = 360.0; + Double lonMax = 0.0; + for (cgCache cache : caches) { + latMin = Math.min(cache.getCoords().getLatitude(), latMin); + latMax = Math.max(cache.getCoords().getLatitude(), latMax); + lonMin = Math.min(cache.getCoords().getLongitude(), lonMin); + lonMax = Math.max(cache.getCoords().getLongitude(), lonMax); } + final List<Number> viewport = new ArrayList<Number>(); + viewport.add(caches.size()); + viewport.add(latMin); + viewport.add(latMax); + viewport.add(lonMin); + viewport.add(lonMax); return viewport; } /** - * Loads a single Cache. + * Load a single Cache. * * @param geocode * The Geocode GCXXXX - * @param guid - * @param loadAttributes - * @param loadWaypoints - * @param loadSpoilers - * @param loadLogs - * @param loadInventory - * @param loadOfflineLogs - * @return the loaded cache + * @return the loaded cache (if found). Can be null */ - public cgCache loadCache(final String geocode, final EnumSet<LoadFlag> loadFlags) { if (StringUtils.isBlank(geocode)) { - return null; + throw new IllegalArgumentException("geocode must not be empty"); } Set<String> geocodes = new HashSet<String>(); geocodes.add(geocode); Set<cgCache> caches = loadCaches(geocodes, loadFlags); - return cgBase.getFirstElementFromSet(caches); + if (caches != null && caches.size() >= 1) { + return (cgCache) caches.toArray()[0]; + } + return null; } + /** + * Load caches. + * + * @param geocodes + * @return Set of loaded caches. Never null. + */ public Set<cgCache> loadCaches(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) { - if (geocodes == null || geocodes.size() == 0) { + if (CollectionUtils.isEmpty(geocodes)) { return new HashSet<cgCache>(); } Set<cgCache> result = new HashSet<cgCache>(); - Set<String> remainingGeocodes = new HashSet<String>(); - for (String geocode : geocodes) { - cgCache cache = cgeoapplication.getCacheFromCache(geocode); - if (cache != null) { - result.add(cache); - } else { - remainingGeocodes.add(geocode); + Set<String> remaining = new HashSet<String>(geocodes); + + if (loadFlags.contains(LoadFlag.LOADCACHEBEFORE)) { + for (String geocode : new HashSet<String>(remaining)) { + cgCache cache = cacheCache.getCacheFromCache(geocode); + if (cache != null) { + result.add(cache); + remaining.remove(cache.getGeocode()); + } + } + } + + if (loadFlags.contains(LoadFlag.LOADDBMINIMAL) || + loadFlags.contains(LoadFlag.LOADATTRIBUTES) || + loadFlags.contains(LoadFlag.LOADWAYPOINTS) || + loadFlags.contains(LoadFlag.LOADSPOILERS) || + loadFlags.contains(LoadFlag.LOADLOGS) || + loadFlags.contains(LoadFlag.LOADINVENTORY) || + loadFlags.contains(LoadFlag.LOADOFFLINELOG)) { + + Set<cgCache> cachesFromDB = loadCaches(remaining, null, null, null, null, loadFlags); + if (cachesFromDB != null) { + result.addAll(cachesFromDB); + for (cgCache cache : cachesFromDB) { + remaining.remove(cache.getGeocode()); + } } } - Set<cgCache> cachesFromDB = loadCaches(remainingGeocodes, null, null, null, null, loadFlags); - if (cachesFromDB != null) { - result.addAll(cachesFromDB); + + if (loadFlags.contains(LoadFlag.LOADCACHEAFTER)) { + for (String geocode : new HashSet<String>(remaining)) { + cgCache cache = cacheCache.getCacheFromCache(geocode); + if (cache != null) { + result.add(cache); + remaining.remove(cache.getGeocode()); + } + } + } + + if (remaining.size() >= 1) { + Log.e(Settings.tag, "cgData.loadCaches(" + remaining.toString() + " failed"); } return result; } + /** + * Load caches. + * + * @param geocodes + * OR + * @param centerLat + * @param centerLon + * @param spanLat + * @param spanLon + * @param loadFlags + * @return Set of loaded caches. Never null. + */ public Set<cgCache> loadCaches(final Set<String> geocodes, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final EnumSet<LoadFlag> loadFlags) { - init(); + final Set<cgCache> caches = new HashSet<cgCache>(); + if (CollectionUtils.isEmpty(geocodes)) { + return caches; + } // Using more than one of the parametersets results in overly comlex wheres - if ((geocodes != null && geocodes.size() > 0) + if (CollectionUtils.isNotEmpty(geocodes) && centerLat != null && centerLon != null && spanLat != null && spanLon != null) { throw new IllegalArgumentException("Please use only one parameter"); } - StringBuilder where = new StringBuilder(); + + Log.d(Settings.tag, "cgData.loadCaches(" + geocodes.toString() + ") from DB"); + + init(); + Cursor cursor = null; - final Set<cgCache> caches = new HashSet<cgCache>(); try { - if (geocodes != null && geocodes.size() > 0) { - StringBuilder all = new StringBuilder(); - for (Object one : geocodes) { - if (all.length() > 0) { - all.append(", "); - } - all.append('"'); - all.append((String) one); - all.append('"'); - } - - if (where.length() > 0) { - where.append(" and "); - } - where.append("geocode in ("); - where.append(all); - where.append(')'); - } else { - return caches; - } + StringBuilder where = cgData.whereGeocodeIn(geocodes); // viewport limitation if (centerLat != null && centerLon != null && spanLat != null && spanLon != null) { @@ -1964,13 +1938,9 @@ public class cgData { cursor.moveToFirst(); do { - //Extracted Method - cgCache cache = createCacheFromDatabaseContent(cursor); + //Extracted Method = LOADDBMINIMAL + cgCache cache = cgData.createCacheFromDatabaseContent(cursor); - // FIXME: in the following code (and similar blocks below), the - // cache.getAttributes() entity probably does not need to be preserved, - // and the resolution of the "if" statement could be simply - // cache.getAttributes() = attributes if (loadFlags.contains(LoadFlag.LOADATTRIBUTES)) { cache.setAttributes(loadAttributes(cache.getGeocode())); } @@ -2019,14 +1989,14 @@ public class cgData { cache.setLogOffline(hasLogOffline(cache.getGeocode())); } cache.addStorageLocation(StorageLocation.DATABASE); - cgeoapplication.putCacheInCache(cache); + cacheCache.putCacheInCache(cache); caches.add(cache); } while (cursor.moveToNext()); } } } catch (Exception e) { - Log.e(Settings.tag, "cgData.loadCaches: " + e.toString()); + Log.e(Settings.tag, "cgData.getCaches: " + e.toString()); } if (cursor != null) { @@ -2037,12 +2007,11 @@ public class cgData { } /** - * maps a Cache from the cursor. Doesn't next. + * creates a Cache from the cursor. Doesn't next. * * @param cursor - * @return + * @return Cache from DB */ - private static cgCache createCacheFromDatabaseContent(Cursor cursor) { int index; cgCache cache = new cgCache(); @@ -2150,6 +2119,9 @@ public class cgData { cache.setOnWatchlist(cursor.getInt(cacheColumnIndex[35]) == 1); cache.setReliableLatLon(cursor.getInt(cacheColumnIndex[36]) > 0); cache.setUserModifiedCoords(cursor.getInt(cacheColumnIndex[37]) > 0); + + Log.d(Settings.tag, "Loading " + cache.toString() + " (" + cache.getListId() + ") from DB"); + return cache; } @@ -2561,10 +2533,20 @@ public class cgData { return trackable; } + /** + * Number of caches stored. The number is shown on the starting activitiy of c:geo + * + * @param detailedOnly + * @param cacheType + * @param list + * @return + */ public int getAllStoredCachesCount(final boolean detailedOnly, final CacheType cacheType, final Integer list) { if (cacheType == null) { throw new IllegalArgumentException("cacheType must not be null"); } + init(); + String listSql = null; String listSqlW = null; if (list == null) { @@ -2619,14 +2601,13 @@ public class cgData { return count; } - public Set<String> loadBatchOfStoredGeocodes(final boolean detailedOnly, final Geopoint coords, final CacheType cacheType, final int list) { + public Set<String> loadBatchOfStoredGeocodes(final boolean detailedOnly, final Geopoint coords, final CacheType cacheType, final int listId) { if (coords == null) { throw new IllegalArgumentException("coords must not be null"); } if (cacheType == null) { throw new IllegalArgumentException("cacheType must not be null"); } - init(); Set<String> geocodes = new HashSet<String>(); @@ -2634,7 +2615,7 @@ public class cgData { StringBuilder specifySql = new StringBuilder(); specifySql.append("reason = "); - specifySql.append(Math.max(list, 1)); + specifySql.append(Math.max(listId, 1)); if (detailedOnly) { specifySql.append(" and detailed = 1 "); @@ -2728,15 +2709,17 @@ public class cgData { return geocodes; } - public Set<String> getCachedInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { - return getInViewport(false, centerLat, centerLon, spanLat, spanLon, cacheType); + /** Retrieve all stored caches from DB */ + public Set<String> loadCachedInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { + return loadInViewport(false, centerLat, centerLon, spanLat, spanLon, cacheType); } - public Set<String> getStoredInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { - return getInViewport(true, centerLat, centerLon, spanLat, spanLon, cacheType); + /** Retrieve stored caches from DB with listId >= 1 */ + public Set<String> loadStoredInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { + return loadInViewport(true, centerLat, centerLon, spanLat, spanLon, cacheType); } - public Set<String> getInViewport(final boolean stored, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { + public Set<String> loadInViewport(final boolean stored, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { if (centerLat == null || centerLon == null || spanLat == null || spanLon == null) { return null; } @@ -2812,7 +2795,7 @@ public class cgData { cursor.close(); } } catch (Exception e) { - Log.e(Settings.tag, "cgData.getOfflineInViewport: " + e.toString()); + Log.e(Settings.tag, "cgData.loadInViewport: " + e.toString()); } return geocodes; @@ -2870,40 +2853,6 @@ public class cgData { return geocodes; } - public void markStored(final String geocode, final int listId) { - if (StringUtils.isBlank(geocode)) { - return; - } - - init(); - - ContentValues values = new ContentValues(); - values.put("reason", Math.max(listId, 1)); - databaseRW.update(dbTableCaches, values, "geocode = ? and reason < 1", new String[] { geocode }); - } - - public boolean markDropped(String geocode) { - if (StringUtils.isBlank(geocode)) { - return false; - } - - init(); - - try { - ContentValues values = new ContentValues(); - values.put("reason", 0); - int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); - - if (rows > 0) { - return true; - } - } catch (Exception e) { - Log.e(Settings.tag, "cgData.markDropped: " + e.toString()); - } - - return false; - } - public boolean markFound(String geocode) { if (StringUtils.isBlank(geocode)) { return false; @@ -2911,32 +2860,47 @@ public class cgData { init(); + boolean result = false; + databaseRW.beginTransaction(); try { ContentValues values = new ContentValues(); values.put("found", 1); int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); - if (rows > 0) { - return true; + // update CacheCache + cgCache cache = cacheCache.getCacheFromCache(geocode); + if (cache != null) { + cache.setFound(true); + cacheCache.putCacheInCache(cache); + } + result = true; } - } catch (Exception e) { - Log.e(Settings.tag, "cgData.markFound: " + e.toString()); + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); } - return false; + return result; } + /** delete caches from the DB store 3 days or more before */ public void clean() { clean(false); } + /** + * Remove caches with listId = 0 + * + * @param more + * true = all caches false = caches stored 3 days or more before + */ public void clean(boolean more) { init(); Log.d(Settings.tag, "Database clean: started"); Cursor cursor = null; - List<String> geocodes = new ArrayList<String>(); + Set<String> geocodes = new HashSet<String>(); try { if (more) { @@ -2978,19 +2942,17 @@ public class cgData { final int size = geocodes.size(); if (size > 0) { - Log.d(Settings.tag, "Database clean: removing " + size + " geocaches"); + Log.d(Settings.tag, "Database clean: removing " + size + " geocaches from listId=0"); - dropCaches(geocodes); + removeCaches(geocodes, EnumSet.of(RemoveFlag.REMOVECACHE)); + databaseRW.execSQL("delete from " + dbTableCaches + " where " + cgData.whereGeocodeIn(geocodes)); } - databaseRW.execSQL("delete from " + dbTableCaches + " where geocode = \"\""); + final SQLiteStatement countSql = databaseRO.compileStatement("select count(_id) from " + dbTableCaches + " where reason = 0"); + final int count = (int) countSql.simpleQueryForLong(); + countSql.close(); + Log.d(Settings.tag, "Database clean: " + count + " geocaches remaining for listId=0"); - if (Log.isLoggable(Settings.tag, Log.DEBUG)) { - final SQLiteStatement countSql = databaseRO.compileStatement("select count(_id) from " + dbTableCaches + " where reason = 0"); - final int count = (int) countSql.simpleQueryForLong(); - countSql.close(); - Log.d(Settings.tag, "Database clean: " + count + " cached geocaches remaining"); - } } catch (Exception e) { Log.w(Settings.tag, "cgData.clean: " + e.toString()); } @@ -2999,49 +2961,79 @@ public class cgData { } /** - * Drop stored list by putting the caches in automatic mode (reason = 0) + * Drop stored list by putting the caches in automatic mode (listId = 0) * * @param listId * the list id to remove the caches from */ - public void dropStored(int listId) { + public void dropList(int listId) { init(); try { final ContentValues values = new ContentValues(); - values.put("reason", 0); + values.put("reason", StoredList.TEMPORARY_LIST_ID); databaseRW.update(dbTableCaches, values, "reason = ?", new String[] { Integer.toString(listId) }); } catch (Exception e) { - Log.e(Settings.tag, "cgData.dropStored: error when updating reason", e); + Log.e(Settings.tag, "cgData.dropList: error when updating reason", e); } } + public void removeAllFromCache() { + // clean up CacheCache + cacheCache.removeAllFromCache(); + } + + public void removeCache(final String geocode, EnumSet<LoadFlags.RemoveFlag> removeFlags) { + Set<String> geocodes = new HashSet<String>(); + geocodes.add(geocode); + removeCaches(geocodes, removeFlags); + } + /** * Drop caches from the tables they are stored into, as well as the cache files * * @param geocodes * list of geocodes to drop from cache */ - public void dropCaches(final List<String> geocodes) { + public void removeCaches(final Set<String> geocodes, EnumSet<LoadFlags.RemoveFlag> removeFlags) { + if (CollectionUtils.isEmpty(geocodes)) { + return; + } + init(); - // Drop caches from the database - final ArrayList<String> quotedGeocodes = new ArrayList<String>(geocodes.size()); - for (final String geocode : geocodes) { - quotedGeocodes.add('"' + geocode + '"'); // FIXME: there ought to be a better way of doing this + + if (removeFlags.contains(RemoveFlag.REMOVECACHE)) { + for (final String geocode : geocodes) { + cacheCache.removeCacheFromCache(geocode); + } } - final String geocodeList = StringUtils.join(quotedGeocodes.toArray(), ','); - final String baseWhereClause = "geocode in (" + geocodeList + ")"; - databaseRW.delete(dbTableCaches, baseWhereClause, null); - databaseRW.delete(dbTableAttributes, baseWhereClause, null); - databaseRW.delete(dbTableSpoilers, baseWhereClause, null); - databaseRW.delete(dbTableLogs, baseWhereClause, null); - databaseRW.delete(dbTableLogCount, baseWhereClause, null); - databaseRW.delete(dbTableLogsOffline, baseWhereClause, null); - databaseRW.delete(dbTableWaypoints, baseWhereClause + " and type <> \"own\"", null); - databaseRW.delete(dbTableTrackables, baseWhereClause, null); - // Delete cache directories - for (final String geocode : geocodes) { - cgBase.deleteDirectory(LocalStorage.getStorageDir(geocode)); + if (removeFlags.contains(RemoveFlag.REMOVEDB)) { + // Drop caches from the database + final ArrayList<String> quotedGeocodes = new ArrayList<String>(geocodes.size()); + for (final String geocode : geocodes) { + quotedGeocodes.add('"' + geocode + '"'); + } + final String geocodeList = StringUtils.join(quotedGeocodes.toArray(), ','); + final String baseWhereClause = "geocode in (" + geocodeList + ")"; + databaseRW.beginTransaction(); + try { + databaseRW.delete(dbTableCaches, baseWhereClause, null); + databaseRW.delete(dbTableAttributes, baseWhereClause, null); + databaseRW.delete(dbTableSpoilers, baseWhereClause, null); + databaseRW.delete(dbTableLogs, baseWhereClause, null); + databaseRW.delete(dbTableLogCount, baseWhereClause, null); + databaseRW.delete(dbTableLogsOffline, baseWhereClause, null); + databaseRW.delete(dbTableWaypoints, baseWhereClause + " and type <> \"own\"", null); + databaseRW.delete(dbTableTrackables, baseWhereClause, null); + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); + } + + // Delete cache directories + for (final String geocode : geocodes) { + cgBase.deleteDirectory(LocalStorage.getStorageDir(geocode)); + } } } @@ -3053,6 +3045,7 @@ public class cgData { return false; } + init(); boolean status = false; ContentValues values = new ContentValues(); @@ -3162,33 +3155,29 @@ public class cgData { return false; } - public void saveVisitDate(String geocode) { - if (StringUtils.isBlank(geocode)) { - return; - } - - ContentValues values = new ContentValues(); - values.put("visiteddate", System.currentTimeMillis()); - - try { - databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); - } catch (Exception e) { - Log.e(Settings.tag, "cgData.saveVisitDate: " + e.toString()); - } - } - - public void clearVisitDate(String geocode) { + public void setVisitDate(String geocode, long visitedDate) { if (StringUtils.isBlank(geocode)) { return; } - ContentValues values = new ContentValues(); - values.put("visiteddate", 0); + init(); + databaseRW.beginTransaction(); try { - databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); - } catch (Exception e) { - Log.e(Settings.tag, "cgData.clearVisitDate: " + e.toString()); + ContentValues values = new ContentValues(); + values.put("visiteddate", visitedDate); + int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); + if (rows > 0) { + // update CacheCache + cgCache cache = cacheCache.getCacheFromCache(geocode); + if (cache != null) { + cache.setFound(true); + cacheCache.putCacheInCache(cache); + } + } + databaseRW.setTransactionSuccessful(); + } finally { + databaseRW.endTransaction(); } } @@ -3239,12 +3228,10 @@ public class cgData { } public StoredList getList(int id, Resources res) { + init(); if (id == StoredList.STANDARD_LIST_ID) { - init(); return new StoredList(StoredList.STANDARD_LIST_ID, res.getString(R.string.list_inbox), (int) getStatementStandardList().simpleQueryForLong()); } else if (id >= 10) { - init(); - Cursor cursor = databaseRO.query( dbTableLists, new String[] { "_id", "title" }, @@ -3326,9 +3313,9 @@ public class cgData { return count; } - public boolean removeList(int id) { + public boolean removeList(int listId) { boolean status = false; - if (id < 10) { + if (listId < 10) { return status; } @@ -3336,12 +3323,12 @@ public class cgData { databaseRW.beginTransaction(); try { - int cnt = databaseRW.delete(dbTableLists, "_id = " + (id - 10), null); + int cnt = databaseRW.delete(dbTableLists, "_id = " + (listId - 10), null); if (cnt > 0) { ContentValues values = new ContentValues(); values.put("reason", 1); - databaseRW.update(dbTableCaches, values, "reason = " + id, null); + databaseRW.update(dbTableCaches, values, "reason = " + listId, null); status = true; } @@ -3355,20 +3342,28 @@ public class cgData { } public void moveToList(String geocode, int listId) { - if (StringUtils.isBlank(geocode) || listId <= 0) { + if (StringUtils.isBlank(geocode)) { return; } + init(); + + ContentValues values = new ContentValues(); + values.put("reason", listId); databaseRW.beginTransaction(); try { - ContentValues values = new ContentValues(); - values.put("reason", listId); databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode }); - databaseRW.setTransactionSuccessful(); } finally { databaseRW.endTransaction(); } + + // update CacheCache + cgCache cache = cacheCache.getCacheFromCache(geocode); + if (cache != null) { + cache.setListId(listId); + cacheCache.putCacheInCache(cache); + } } public synchronized boolean status() { @@ -3387,7 +3382,6 @@ public class cgData { init(); databaseRW.beginTransaction(); - try { databaseRW.delete(dbTableSearchDestionationHistory, "_id = " + destination.getId(), null); databaseRW.setTransactionSuccessful(); @@ -3409,8 +3403,22 @@ public class cgData { return statementDescription; } + private synchronized SQLiteStatement getStatementCacheId() { + if (statementDescription == null) { + statementDescription = databaseRO.compileStatement("SELECT cacheid FROM " + dbTableCaches + " WHERE geocode = ?"); + } + return statementDescription; + } + + private synchronized SQLiteStatement getStatementGeocode() { + if (statementDescription == null) { + statementDescription = databaseRO.compileStatement("SELECT geocode FROM " + dbTableCaches + " WHERE guid = ?"); + } + return statementDescription; + } + public String getCacheDescription(String geocode) { - if (geocode == null) { + if (StringUtils.isBlank(geocode)) { return null; } init(); @@ -3445,4 +3453,27 @@ public class cgData { public static void resetNewlyCreatedDatabase() { newlyCreatedDatabase = false; } + + private static StringBuilder whereGeocodeIn(Set<String> geocodes) { + final StringBuilder where = new StringBuilder(); + + if (geocodes != null && geocodes.size() > 0) { + StringBuilder all = new StringBuilder(); + for (String geocode : geocodes) { + if (all.length() > 0) { + all.append(", "); + } + all.append('"'); + all.append(geocode); + all.append('"'); + } + + where.append("geocode in ("); + where.append(all); + where.append(')'); + } + + return where; + } + } diff --git a/main/src/cgeo/geocaching/cgWaypoint.java b/main/src/cgeo/geocaching/cgWaypoint.java index ed0e038..c3e2d2b 100644 --- a/main/src/cgeo/geocaching/cgWaypoint.java +++ b/main/src/cgeo/geocaching/cgWaypoint.java @@ -228,4 +228,9 @@ public class cgWaypoint implements IWaypoint, Comparable<cgWaypoint> { this.cachedOrder = cachedOrder; } + @Override + public String toString() { + return name + " " + waypointType.getL10n(); + } + }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/cgeo.java b/main/src/cgeo/geocaching/cgeo.java index 4de8e50..4a77524 100644 --- a/main/src/cgeo/geocaching/cgeo.java +++ b/main/src/cgeo/geocaching/cgeo.java @@ -776,6 +776,10 @@ public class cgeo extends AbstractActivity { updateUserInfoHandler.sendEmptyMessage(-1); } + // TODO blafoo remove + // cgeoapplication.getInstance().cleanDatabase(true); + // Settings.setDebugInfos(true); + if (app.showLoginToast) { firstLoginHandler.sendMessage(firstLoginHandler.obtainMessage(0, status)); app.showLoginToast = false; diff --git a/main/src/cgeo/geocaching/cgeoapplication.java b/main/src/cgeo/geocaching/cgeoapplication.java index c876d13..600ec04 100644 --- a/main/src/cgeo/geocaching/cgeoapplication.java +++ b/main/src/cgeo/geocaching/cgeoapplication.java @@ -4,10 +4,10 @@ import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.LoadFlag; +import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.geopoint.Geopoint; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import android.app.Activity; @@ -56,7 +56,7 @@ public class cgeoapplication extends Application { public void onLowMemory() { Log.i(Settings.tag, "Cleaning applications cache."); - CacheCache.getInstance().removeAll(); + storage.removeAllFromCache(); } @Override @@ -222,18 +222,22 @@ public class cgeoapplication extends Application { databaseCleaned = true; } + /** {@link cgData#isThere(String, String, boolean, boolean)} */ public boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { return storage.isThere(geocode, guid, detailed, checkTime); } + /** {@link cgData#isOffline(String, String)} */ public boolean isOffline(String geocode, String guid) { return storage.isOffline(geocode, guid); } + /** {@link cgData#getGeocodeForGuid(String)} */ public String getGeocode(String guid) { return storage.getGeocodeForGuid(guid); } + /** {@link cgData#getCacheidForGeocode(String)} */ public String getCacheid(String geocode) { return storage.getCacheidForGeocode(geocode); } @@ -251,20 +255,6 @@ public class cgeoapplication extends Application { return false; } - public cgCache getCacheByGeocode(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - return getCacheByGeocode(geocode, LoadFlags.LOADALL); - } - - public cgCache getCacheByGeocode(final String geocode, final EnumSet<LoadFlag> loadFlags) { - - return storage.loadCache(geocode, loadFlags); - - } - public cgTrackable getTrackableByGeocode(String geocode) { if (StringUtils.isBlank(geocode)) { return null; @@ -276,18 +266,7 @@ public class cgeoapplication extends Application { return trackable; } - public static void removeCacheFromCache(final String geocode) { - CacheCache.getInstance().removeCacheFromCache(geocode); - } - - public static void putCacheInCache(final cgCache cache) { - CacheCache.getInstance().putCacheInCache(cache); - } - - public static cgCache getCacheFromCache(final String geocode) { - return CacheCache.getInstance().getCacheFromCache(geocode); - } - + /** {@link cgData#allDetailedThere()} */ public String[] geocodesInCache() { return storage.allDetailedThere(); } @@ -303,61 +282,20 @@ public class cgeoapplication extends Application { return getBounds(geocodeList); } - public List<Number> getBounds(final SearchResult search) { - if (search == null) { - return null; - } - - return getBounds(search.getGeocodes()); - } - + /** {@link cgData#getBounds(Set)} */ public List<Number> getBounds(final Set<String> geocodes) { - if (CollectionUtils.isEmpty(geocodes)) { - return null; - } - - return storage.getBounds(geocodes.toArray()); - } - - public cgCache getCache(final SearchResult search) { - if (search == null || search.getCount() < 1) { - return null; - } - - final Set<String> geocodeList = search.getGeocodes(); - - return getCacheByGeocode(geocodeList.toArray(new String[geocodeList.size()])[0], LoadFlags.LOADALL); - } - - /** - * @param search - * @param loadWaypoints - * only load waypoints for map usage. All other callers should set this to <code>false</code> - * @return - */ - public Set<cgCache> getCaches(final SearchResult search, final boolean loadWaypoints) { - return storage.loadCaches(search.getGeocodes(), loadWaypoints ? EnumSet.of(LoadFlag.LOADWAYPOINTS, LoadFlag.LOADOFFLINELOG) : EnumSet.of(LoadFlag.LOADOFFLINELOG)); - } - - public Set<cgCache> getCaches(final SearchResult search, Long centerLat, Long centerLon, Long spanLat, Long spanLon) { - if (search == null) { - final Set<cgCache> cachesPre = storage.loadCaches(null, centerLat, centerLon, spanLat, spanLon, EnumSet.of(LoadFlag.LOADWAYPOINTS, LoadFlag.LOADOFFLINELOG)); - return cachesPre != null ? cachesPre : new HashSet<cgCache>(); - } - - // The list of geocodes is sufficient. more parameters generate an overly complex select. - final Set<cgCache> cachesPre = storage.loadCaches(search.getGeocodes(), EnumSet.of(LoadFlag.LOADWAYPOINTS, LoadFlag.LOADOFFLINELOG)); - return cachesPre != null ? cachesPre : new HashSet<cgCache>(); - + return storage.getBounds(geocodes); } - public SearchResult getBatchOfStoredCaches(final boolean detailedOnly, final Geopoint coords, final CacheType cacheType, final int list) { - final Set<String> geocodes = storage.loadBatchOfStoredGeocodes(detailedOnly, coords, cacheType, list); + /** {@link cgData#loadBatchOfStoredGeocodes(boolean, Geopoint, CacheType, int)} */ + public SearchResult getBatchOfStoredCaches(final boolean detailedOnly, final Geopoint coords, final CacheType cacheType, final int listId) { + final Set<String> geocodes = storage.loadBatchOfStoredGeocodes(detailedOnly, coords, cacheType, listId); final SearchResult search = new SearchResult(geocodes); - search.totalCnt = getAllStoredCachesCount(true, cacheType, list); + search.totalCnt = getAllStoredCachesCount(true, cacheType, listId); return search; } + /** {@link cgData#loadHistoryOfSearchedLocations()} */ public List<cgDestination> getHistoryOfSearchedLocations() { return storage.loadHistoryOfSearchedLocations(); } @@ -365,60 +303,72 @@ public class cgeoapplication extends Application { public SearchResult getHistoryOfCaches(final boolean detailedOnly, final CacheType cacheType) { final Set<String> geocodes = storage.loadBatchOfHistoricGeocodes(detailedOnly, cacheType); final SearchResult search = new SearchResult(geocodes); + search.totalCnt = getAllHistoricCachesCount(); return search; } + /** {@link cgData#loadCachedInViewport(Long, Long, Long, Long, CacheType)} */ public SearchResult getCachedInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { - final Set<String> geocodes = storage.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, cacheType); + final Set<String> geocodes = storage.loadCachedInViewport(centerLat, centerLon, spanLat, spanLon, cacheType); return new SearchResult(geocodes); } + /** {@link cgData#loadStoredInViewport(Long, Long, Long, Long, CacheType)} */ public SearchResult getStoredInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) { - final Set<String> geocodes = storage.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, cacheType); + final Set<String> geocodes = storage.loadStoredInViewport(centerLat, centerLon, spanLat, spanLon, cacheType); return new SearchResult(geocodes); } + /** {@link cgData#getAllStoredCachesCount(boolean, CacheType, Integer)} */ public int getAllStoredCachesCount(final boolean detailedOnly, final CacheType cacheType, final Integer list) { return storage.getAllStoredCachesCount(detailedOnly, cacheType, list); } + /** {@link cgData#getAllHistoricCachesCount()} */ public int getAllHistoricCachesCount() { return storage.getAllHistoricCachesCount(); } + /** {@link cgData#moveToList(String, int)} */ public void markStored(String geocode, int listId) { - storage.markStored(geocode, listId); + storage.moveToList(geocode, listId); } - public boolean markDropped(String geocode) { - return storage.markDropped(geocode); + /** {@link cgData#moveToList(String, int)} */ + public void markDropped(String geocode) { + storage.moveToList(geocode, StoredList.TEMPORARY_LIST_ID); } + /** {@link cgData#markFound(String)} */ public boolean markFound(String geocode) { return storage.markFound(geocode); } + /** {@link cgData#clearSearchedDestinations()} */ public boolean clearSearchedDestinations() { return storage.clearSearchedDestinations(); } + /** {@link cgData#saveSearchedDestination(cgDestination)} */ public boolean saveSearchedDestination(cgDestination destination) { return storage.saveSearchedDestination(destination); } + /** {@link cgData#saveWaypoints(String, List, boolean)} */ public boolean saveWaypoints(String geocode, List<cgWaypoint> waypoints, boolean drop) { return storage.saveWaypoints(geocode, waypoints, drop); } public boolean saveOwnWaypoint(int id, String geocode, cgWaypoint waypoint) { if (storage.saveOwnWaypoint(id, geocode, waypoint)) { - removeCacheFromCache(geocode); + this.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVECACHE)); return true; } return false; } + /** {@link cgData#deleteWaypoint(int)} */ public boolean deleteWaypoint(int id) { return storage.deleteWaypoint(id); } @@ -430,73 +380,27 @@ public class cgeoapplication extends Application { return storage.saveInventory("---", list); } - public void addSearch(final Set<cgCache> cacheList, final int listId) { - if (CollectionUtils.isEmpty(cacheList)) { - return; - } - - for (final cgCache cache : cacheList) { - cache.setListId(listId); - storeWithMerge(cache, false); - } - } - - public boolean addCacheToSearch(SearchResult search, cgCache cache) { - if (search == null || cache == null) { - return false; - } - - final boolean status = storeWithMerge(cache, cache.getListId() >= 1); - if (status) { - search.addGeocode(cache.getGeocode()); - } - - return status; - } - - /** - * Checks if Cache is already in Database and if so does a merge. - * - * @param cache - * the cache to be saved - * @param override - * override the check and persist the new state. - * @return true if the cache has been saved correctly - */ - - private boolean storeWithMerge(final cgCache cache, final boolean override) { - boolean saveCache = true; - if (!override) { - final cgCache oldCache = storage.loadCache(cache.getGeocode(), LoadFlags.LOADALL); - saveCache = !cache.gatherMissingFrom(oldCache); - } - return saveCache ? storage.saveCache(cache) : true; - - } - - public void dropStored(int listId) { - storage.dropStored(listId); - } - - /** - * {@link cgData#dropCaches(List)} - */ - public void dropCaches(final List<String> geocodes) { - storage.dropCaches(geocodes); + /** {@link cgData#dropList(int)} **/ + public void dropList(int listId) { + storage.dropList(listId); } + /** {@link cgData#loadInventory(String)} */ public List<cgTrackable> loadInventory(String geocode) { return storage.loadInventory(geocode); } + /** {@link cgData#loadLogCounts(String)} */ public Map<LogType, Integer> loadLogCounts(String geocode) { return storage.loadLogCounts(geocode); } + /** {@link cgData#loadSpoilers(String)} */ public List<cgImage> loadSpoilers(String geocode) { return storage.loadSpoilers(geocode); } + /** {@link cgData#loadWaypoint(int)} */ public cgWaypoint loadWaypoint(int id) { return storage.loadWaypoint(id); } @@ -542,55 +446,99 @@ public class cgeoapplication extends Application { return lastCoords; } + /** {@link cgData#saveLogOffline(String, Date, LogType, String)} */ public boolean saveLogOffline(String geocode, Date date, LogType logtype, String log) { return storage.saveLogOffline(geocode, date, logtype, log); } + /** {@link cgData#loadLogOffline(String)} */ public cgLog loadLogOffline(String geocode) { return storage.loadLogOffline(geocode); } + /** {@link cgData#clearLogOffline(String)} */ public void clearLogOffline(String geocode) { storage.clearLogOffline(geocode); } + /** {@link cgData#setVisitDate(String, long)} */ public void saveVisitDate(String geocode) { - storage.saveVisitDate(geocode); + storage.setVisitDate(geocode, System.currentTimeMillis()); } + /** {@link cgData#setVisitDate(String, long)} */ public void clearVisitDate(String geocode) { - storage.clearVisitDate(geocode); + storage.setVisitDate(geocode, 0); } + /** {@link cgData#getLists(Resources)} */ public List<StoredList> getLists() { return storage.getLists(getResources()); } + /** {@link cgData#getList(int, Resources))} */ public StoredList getList(int id) { return storage.getList(id, getResources()); } + /** {@link cgData#createList(String)} */ public int createList(String title) { return storage.createList(title); } + /** {@link cgData#renameList(int, String)} */ public int renameList(final int listId, final String title) { return storage.renameList(listId, title); } + /** {@link cgData#removeList(int)} */ public boolean removeList(int id) { return storage.removeList(id); } + /** {@link cgData#removeSearchedDestination(cgDestination)} */ public boolean removeSearchedDestinations(cgDestination destination) { return storage.removeSearchedDestination(destination); } + /** {@link cgData#moveToList(String, int)} */ public void moveToList(String geocode, int listId) { storage.moveToList(geocode, listId); } + /** {@link cgData#getCacheDescription(String)} */ public String getCacheDescription(String geocode) { return storage.getCacheDescription(geocode); } + + /** {@link cgData#loadCaches} */ + public cgCache loadCache(final String geocode, final EnumSet<LoadFlag> loadFlags) { + return storage.loadCache(geocode, loadFlags); + } + + /** {@link cgData#loadCaches} */ + public Set<cgCache> loadCaches(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) { + return storage.loadCaches(geocodes, loadFlags); + } + + /** {@link cgData#loadCaches} */ + public Set<cgCache> loadCaches(Long centerLat, Long centerLon, Long spanLat, Long spanLon, final EnumSet<LoadFlag> loadFlags) { + return storage.loadCaches(null, centerLat, centerLon, spanLat, spanLon, loadFlags); + } + + /** {@link cgData#saveCache} */ + public boolean saveCache(cgCache cache, EnumSet<LoadFlags.SaveFlag> saveFlags) { + return storage.saveCache(cache, saveFlags); + } + + /** {@link cgData#removeCache} */ + public void removeCache(String geocode, EnumSet<LoadFlags.RemoveFlag> removeFlags) { + storage.removeCache(geocode, removeFlags); + } + + /** {@link cgData#removeCaches} */ + public void removeCaches(final Set<String> geocodes, EnumSet<LoadFlags.RemoveFlag> removeFlags) { + storage.removeCaches(geocodes, removeFlags); + } + } diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java index b2e5489..119aeda 100644 --- a/main/src/cgeo/geocaching/cgeocaches.java +++ b/main/src/cgeo/geocaching/cgeocaches.java @@ -7,6 +7,7 @@ import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.apps.cachelist.CacheListAppFactory; import cgeo.geocaching.enumerations.CacheListType; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.files.GPXImporter; @@ -160,7 +161,7 @@ public class cgeocaches extends AbstractListActivity { private DropDetailsThread threadR = null; private ExportFieldNotesThread threadF = null; private RemoveFromHistoryThread threadH = null; - private int listId = 0; + private int listId = StoredList.TEMPORARY_LIST_ID; private List<StoredList> lists = null; private GeocodeComparator gcComparator = new GeocodeComparator(); private Handler loadCachesHandler = new Handler() { @@ -169,14 +170,12 @@ public class cgeocaches extends AbstractListActivity { public void handleMessage(Message msg) { try { if (search != null) { - setTitle(title + " [" + SearchResult.getCount(search) + "]"); + setTitle(title + " [" + search.getCount() + "]"); cacheList.clear(); - final Set<cgCache> cacheListTmp = app.getCaches(search, false); - if (CollectionUtils.isNotEmpty(cacheListTmp)) { - cacheList.addAll(cacheListTmp); - cacheListTmp.clear(); - + final Set<cgCache> caches = search.getCachesFromSearchResult(LoadFlags.LOADCACHEORDB); + if (CollectionUtils.isNotEmpty(caches)) { + cacheList.addAll(caches); Collections.sort(cacheList, gcComparator); } } else { @@ -192,7 +191,7 @@ public class cgeocaches extends AbstractListActivity { } setMoreCaches(); - if (cacheList != null && SearchResult.getError(search) == StatusCode.UNAPPROVED_LICENSE) { + if (cacheList != null && search != null && search.getError() == StatusCode.UNAPPROVED_LICENSE) { AlertDialog.Builder dialog = new AlertDialog.Builder(cgeocaches.this); dialog.setTitle(res.getString(R.string.license)); dialog.setMessage(res.getString(R.string.err_license)); @@ -214,8 +213,8 @@ public class cgeocaches extends AbstractListActivity { AlertDialog alert = dialog.create(); alert.show(); - } else if (app != null && SearchResult.getError(search) != null) { - showToast(res.getString(R.string.err_download_fail) + " " + SearchResult.getError(search).getErrorString(res) + "."); + } else if (app != null && search != null && search.getError() != null) { + showToast(res.getString(R.string.err_download_fail) + " " + search.getError().getErrorString(res) + "."); hideLoading(); showProgress(false); @@ -257,13 +256,13 @@ public class cgeocaches extends AbstractListActivity { public void handleMessage(Message msg) { try { if (search != null) { - setTitle(title + " [" + SearchResult.getCount(search) + "]"); + setTitle(title + " [" + search.getCount() + "]"); cacheList.clear(); - final Set<cgCache> cacheListTmp = app.getCaches(search, false); - if (CollectionUtils.isNotEmpty(cacheListTmp)) { - cacheList.addAll(cacheListTmp); - cacheListTmp.clear(); + final Set<cgCache> caches = search.getCachesFromSearchResult(LoadFlags.LOADCACHEORDB); + if (CollectionUtils.isNotEmpty(caches)) { + cacheList.addAll(caches); + caches.clear(); Collections.sort(cacheList, gcComparator); } if (adapter != null) { @@ -280,8 +279,8 @@ public class cgeocaches extends AbstractListActivity { } setMoreCaches(); - if (SearchResult.getError(search) != null) { - showToast(res.getString(R.string.err_download_fail) + " " + SearchResult.getError(search).getErrorString(res) + "."); + if (search != null && search.getError() != null) { + showToast(res.getString(R.string.err_download_fail) + " " + search.getError().getErrorString(res) + "."); listFooter.setOnClickListener(new MoreCachesListener()); hideLoading(); @@ -336,7 +335,7 @@ public class cgeocaches extends AbstractListActivity { } } else { if (cacheList != null && search != null) { - final Set<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = search.getCachesFromSearchResult(LoadFlags.LOADCACHEORDB); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.clear(); cacheList.addAll(cacheListTmp); @@ -404,7 +403,7 @@ public class cgeocaches extends AbstractListActivity { cacheList.clear(); - final Set<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = search.getCachesFromSearchResult(LoadFlags.LOADCACHEORDB); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.addAll(cacheListTmp); cacheListTmp.clear(); @@ -431,7 +430,7 @@ public class cgeocaches extends AbstractListActivity { cacheList.clear(); - final Set<cgCache> cacheListTmp = app.getCaches(search, false); + final Set<cgCache> cacheListTmp = search.getCachesFromSearchResult(LoadFlags.LOADCACHEORDB); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.addAll(cacheListTmp); cacheListTmp.clear(); @@ -558,7 +557,7 @@ public class cgeocaches extends AbstractListActivity { switch (type) { case OFFLINE: listId = Settings.getLastList(); - if (listId <= 0) { + if (listId <= StoredList.TEMPORARY_LIST_ID) { listId = StoredList.STANDARD_LIST_ID; title = res.getString(R.string.stored_caches_button); } else { @@ -658,7 +657,7 @@ public class cgeocaches extends AbstractListActivity { setTitle(title); showProgress(true); SearchResult result = extras != null ? (SearchResult) extras.get("search") : null; - search = new ParseResult(result); + search = new SearchResult(result); loadCachesHandler.sendMessage(Message.obtain()); break; default: @@ -724,7 +723,7 @@ public class cgeocaches extends AbstractListActivity { // refresh standard list if it has changed (new caches downloaded) if (type == CacheListType.OFFLINE && listId >= StoredList.STANDARD_LIST_ID && search != null) { - SearchResult newSearch = cgBase.searchByOffline(coords, cacheType, listId); + SearchResult newSearch = cgBase.searchByStored(coords, cacheType, listId); if (newSearch != null && newSearch.totalCnt != search.totalCnt) { refreshCurrentList(); } @@ -868,7 +867,7 @@ public class cgeocaches extends AbstractListActivity { } boolean hasSelection = adapter != null && adapter.getChecked() > 0; - boolean isNonDefaultList = listId != 1; + boolean isNonDefaultList = listId != StoredList.STANDARD_LIST_ID; if (type == CacheListType.OFFLINE) { // only offline list if (hasSelection) { @@ -1224,7 +1223,7 @@ public class cgeocaches extends AbstractListActivity { return true; } else if (id == MENU_DROP_CACHE) { - cgBase.dropCache(app, getCacheFromAdapter(adapterInfo), new Handler() { + cgBase.dropCache(getCacheFromAdapter(adapterInfo), new Handler() { @Override public void handleMessage(Message msg) { refreshCurrentList(); @@ -1366,8 +1365,8 @@ public class cgeocaches extends AbstractListActivity { } boolean enableMore = type != CacheListType.OFFLINE && cacheList != null && cacheList.size() < MAX_LIST_ITEMS; - if (enableMore) { - final int count = SearchResult.getTotal(search); + if (enableMore && search != null) { + final int count = search.getTotal(); enableMore = enableMore && count > 0 && cacheList.size() < count; } @@ -1731,7 +1730,7 @@ public class cgeocaches extends AbstractListActivity { @Override public void run() { - search = cgBase.searchByOffline(coords, Settings.getCacheType(), listId); + search = cgBase.searchByStored(coords, Settings.getCacheType(), listId); handler.sendMessage(new Message()); } } @@ -1761,7 +1760,7 @@ public class cgeocaches extends AbstractListActivity { @Override public void run() { - search = cgBase.searchByNextPage(this, (ParseResult) search, 0, Settings.isShowCaptcha()); + search = cgBase.searchByNextPage(this, search, 0, Settings.isShowCaptcha()); handler.sendMessage(new Message()); } @@ -2536,7 +2535,7 @@ public class cgeocaches extends AbstractListActivity { searchToUse = new SearchResult(geocodes); } - int count = SearchResult.getCount(searchToUse); + int count = searchToUse.getCount(); String mapTitle = title; if (count > 0) { mapTitle = title + " [" + count + "]"; diff --git a/main/src/cgeo/geocaching/cgeogpxes.java b/main/src/cgeo/geocaching/cgeogpxes.java index 0ecc9e7..205ee59 100644 --- a/main/src/cgeo/geocaching/cgeogpxes.java +++ b/main/src/cgeo/geocaching/cgeogpxes.java @@ -23,7 +23,7 @@ public class cgeogpxes extends FileList<GPXListAdapter> { super(new String[] { "gpx", "loc", "zip" });
}
- private int listId = 1;
+ private int listId = StoredList.STANDARD_LIST_ID;
@Override
protected GPXListAdapter getAdapter(List<File> files) {
@@ -43,7 +43,7 @@ public class cgeogpxes extends FileList<GPXListAdapter> { if (extras != null) {
listId = extras.getInt(EXTRAS_LIST_ID);
}
- if (listId <= 0) {
+ if (listId <= StoredList.TEMPORARY_LIST_ID) {
listId = StoredList.STANDARD_LIST_ID;
}
}
diff --git a/main/src/cgeo/geocaching/cgeopopup.java b/main/src/cgeo/geocaching/cgeopopup.java index 1210efc..4deb5bc 100644 --- a/main/src/cgeo/geocaching/cgeopopup.java +++ b/main/src/cgeo/geocaching/cgeopopup.java @@ -4,6 +4,7 @@ import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.gcvote.GCVote; import cgeo.geocaching.gcvote.GCVoteRating; @@ -199,7 +200,7 @@ public class cgeopopup extends AbstractActivity { app.setAction(geocode); - cache = app.getCacheByGeocode(geocode); + cache = app.loadCache(geocode, LoadFlags.LOADCACHEORDB); if (cache == null) { showToast(res.getString(R.string.err_detail_cache_find)); @@ -586,7 +587,7 @@ public class cgeopopup extends AbstractActivity { @Override public void run() { - cgBase.dropCache(app, cache, handler); + cgBase.dropCache(cache, handler); } } diff --git a/main/src/cgeo/geocaching/cgeotouch.java b/main/src/cgeo/geocaching/cgeotouch.java index d261687..6271ec1 100644 --- a/main/src/cgeo/geocaching/cgeotouch.java +++ b/main/src/cgeo/geocaching/cgeotouch.java @@ -444,7 +444,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog if (status == StatusCode.NO_ERROR && Settings.isUseTwitter() && Settings.isTwitterLoginValid() && tweetCheck.isChecked() && tweetBox.getVisibility() == View.VISIBLE) { - cgBase.postTweetTrackable(app, geocode); + cgBase.postTweetTrackable(geocode); } return status; diff --git a/main/src/cgeo/geocaching/cgeowaypoint.java b/main/src/cgeo/geocaching/cgeowaypoint.java index a46a969..55b0e01 100644 --- a/main/src/cgeo/geocaching/cgeowaypoint.java +++ b/main/src/cgeo/geocaching/cgeowaypoint.java @@ -2,6 +2,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; +import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; import org.apache.commons.lang3.StringUtils; @@ -21,6 +22,8 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import java.util.EnumSet; + public class cgeowaypoint extends AbstractActivity { private static final int MENU_ID_NAVIGATION = 0; @@ -310,7 +313,7 @@ public class cgeowaypoint extends AbstractActivity { public void onClick(View arg0) { if (app.deleteWaypoint(id)) { StaticMapsProvider.removeWpStaticMaps(id, geocode); - cgeoapplication.removeCacheFromCache(geocode); + app.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVECACHE)); finish(); return; diff --git a/main/src/cgeo/geocaching/cgeowaypointadd.java b/main/src/cgeo/geocaching/cgeowaypointadd.java index 66e000e..fd5ba91 100644 --- a/main/src/cgeo/geocaching/cgeowaypointadd.java +++ b/main/src/cgeo/geocaching/cgeowaypointadd.java @@ -2,6 +2,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; @@ -229,7 +230,7 @@ public class cgeowaypointadd extends AbstractActivity { if (waypoint != null && waypoint.getCoords() != null) { gp = waypoint.getCoords(); } - cgCache cache = app.getCacheByGeocode(geocode); + cgCache cache = app.loadCache(geocode, LoadFlags.LOADWAYPOINTS); cgeocoords coordsDialog = new cgeocoords(cgeowaypointadd.this, cache, gp, geo); coordsDialog.setCancelable(true); coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { @@ -323,7 +324,7 @@ public class cgeowaypointadd extends AbstractActivity { if (app.saveOwnWaypoint(id, geocode, waypoint)) { StaticMapsProvider.removeWpStaticMaps(id, geocode); if (Settings.isStoreOfflineWpMaps()) { - StaticMapsProvider.storeWaypointStaticMap(app.getCacheByGeocode(geocode), cgeowaypointadd.this, waypoint); + StaticMapsProvider.storeWaypointStaticMap(app.loadCache(geocode, LoadFlags.LOADCACHEORDB), cgeowaypointadd.this, waypoint); } finish(); return; diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java index 9abcd45..6db305c 100644 --- a/main/src/cgeo/geocaching/connector/AbstractConnector.java +++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java @@ -1,6 +1,6 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.ParseResult; +import cgeo.geocaching.SearchResult; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.geopoint.Geopoint; @@ -44,12 +44,12 @@ public abstract class AbstractConnector implements IConnector { } @Override - public ParseResult searchByCoordinate(Geopoint center) { + public SearchResult searchByCoordinate(Geopoint center) { return null; } @Override - public ParseResult searchByGeocode(String geocode, String guid, cgeoapplication app, int listId, CancellableHandler handler) { + public SearchResult searchByGeocode(String geocode, String guid, cgeoapplication app, int listId, CancellableHandler handler) { return null; } diff --git a/main/src/cgeo/geocaching/connector/GCConnector.java b/main/src/cgeo/geocaching/connector/GCConnector.java index f65312c..2c198ae 100644 --- a/main/src/cgeo/geocaching/connector/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/GCConnector.java @@ -1,8 +1,8 @@ package cgeo.geocaching.connector; import cgeo.geocaching.GCConstants; -import cgeo.geocaching.ParseResult; import cgeo.geocaching.R; +import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; @@ -81,7 +81,7 @@ public class GCConnector extends AbstractConnector { } @Override - public ParseResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final int listId, final CancellableHandler handler) { + public SearchResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final int listId, final CancellableHandler handler) { if (app == null) { Log.e(Settings.tag, "cgeoBase.searchByGeocode: No application found"); @@ -102,7 +102,7 @@ public class GCConnector extends AbstractConnector { final String page = cgBase.requestLogged("http://www.geocaching.com/seek/cache_details.aspx", params, false, false, false); if (StringUtils.isEmpty(page)) { - ParseResult search = new ParseResult(); + SearchResult search = new SearchResult(); if (app.isThere(geocode, guid, true, false)) { if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) { Log.i(Settings.tag, "Loading old cache from cache."); @@ -120,16 +120,14 @@ public class GCConnector extends AbstractConnector { return search; } - final ParseResult parseResult = cgBase.parseCache(page, listId, handler); - - if (parseResult == null || CollectionUtils.isEmpty(parseResult.cacheList)) { + final SearchResult searchResult = cgBase.parseCache(page, listId, handler); + if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) { Log.e(Settings.tag, "cgeoBase.searchByGeocode: No cache parsed"); - return parseResult; + return searchResult; } - ParseResult search = ParseResult.filterParseResults(parseResult, false, false, Settings.getCacheType()); - app.addSearch(search.cacheList, listId); + SearchResult search = searchResult.filterSearchResults(false, false, Settings.getCacheType(), listId); return search; } diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java index 7fa0e3f..028f79b 100644 --- a/main/src/cgeo/geocaching/connector/IConnector.java +++ b/main/src/cgeo/geocaching/connector/IConnector.java @@ -1,6 +1,6 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.ParseResult; +import cgeo.geocaching.SearchResult; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.geopoint.Geopoint; @@ -75,7 +75,7 @@ public interface IConnector { */ public boolean supportsCachesAround(); - public ParseResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final int listId, final CancellableHandler handler); + public SearchResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final int listId, final CancellableHandler handler); /** * search caches by coordinate. must be implemented if {@link supportsCachesAround} returns <code>true</true> @@ -83,7 +83,7 @@ public interface IConnector { * @param center * @return */ - public ParseResult searchByCoordinate(final Geopoint center); + public SearchResult searchByCoordinate(final Geopoint center); /** * return true if this is a ZIP file containing a GPX file diff --git a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java index c5d7f3c..e72a1e3 100644 --- a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java +++ b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java @@ -1,6 +1,6 @@ package cgeo.geocaching.connector.opencaching; -import cgeo.geocaching.ParseResult; +import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; @@ -33,17 +33,15 @@ public class ApiOpenCachingConnector extends OpenCachingConnector { } @Override - public ParseResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final int listId, final CancellableHandler handler) { + public SearchResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final int listId, final CancellableHandler handler) { final cgCache cache = OkapiClient.getCache(geocode); if (cache == null) { return null; } - final ParseResult parseResult = new ParseResult(); - parseResult.cacheList.add(cache); - - final ParseResult search = ParseResult.filterParseResults(parseResult, false, false, Settings.getCacheType()); - app.addSearch(search.cacheList, listId); + final SearchResult searchResult = new SearchResult(); + searchResult.addCache(cache); + final SearchResult search = searchResult.filterSearchResults(false, false, Settings.getCacheType(), listId); return search; } } diff --git a/main/src/cgeo/geocaching/enumerations/LoadFlags.java b/main/src/cgeo/geocaching/enumerations/LoadFlags.java index dfdd52f..875bb98 100644 --- a/main/src/cgeo/geocaching/enumerations/LoadFlags.java +++ b/main/src/cgeo/geocaching/enumerations/LoadFlags.java @@ -3,13 +3,16 @@ package cgeo.geocaching.enumerations; import java.util.EnumSet; /** - * Cache loading parameters - * + * Cache loading/saving/removing parameters + * * @author blafoo */ public class LoadFlags { public enum LoadFlag { + LOADCACHEBEFORE, // load from CacheCache + LOADCACHEAFTER, // load from CacheCache + LOADDBMINIMAL, // load minimal informations from DataBase LOADATTRIBUTES, LOADWAYPOINTS, LOADSPOILERS, @@ -18,6 +21,27 @@ public class LoadFlags { LOADOFFLINELOG } - public final static EnumSet<LoadFlag> LOADALL = EnumSet.allOf(LoadFlag.class); + /** Retrieve cache from CacheCache only. Do not load from DB */ + public final static EnumSet<LoadFlag> LOADCACHEONLY = EnumSet.of(LoadFlag.LOADCACHEBEFORE); + /** Retrieve cache from CacheCache first. If not found load from DB */ + public final static EnumSet<LoadFlag> LOADCACHEORDB = EnumSet.of(LoadFlag.LOADCACHEBEFORE, LoadFlag.LOADDBMINIMAL); + /** Retrieve cache (minimalistic informations including waypoints) from DB first. If not found load from CacheCache */ + public final static EnumSet<LoadFlag> LOADWAYPOINTS = EnumSet.of(LoadFlag.LOADCACHEAFTER, LoadFlag.LOADDBMINIMAL, LoadFlag.LOADWAYPOINTS); + /** Retrieve cache (all stored informations) from DB only. Do not load from CacheCache */ + public final static EnumSet<LoadFlag> LOADALLDBONLY = EnumSet.range(LoadFlag.LOADDBMINIMAL, LoadFlag.LOADOFFLINELOG); + + public enum SaveFlag { + SAVECACHE, // save only to CacheCache + SAVEDB // include saving to CacheCache + } + + public final static EnumSet<SaveFlag> SAVEALL = EnumSet.allOf(SaveFlag.class); + + public enum RemoveFlag { + REMOVECACHE, // save only to CacheCache + REMOVEDB // includes removing from CacheCache + } + + public final static EnumSet<RemoveFlag> REMOVEALL = EnumSet.allOf(RemoveFlag.class); }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/files/FileList.java b/main/src/cgeo/geocaching/files/FileList.java index 2ad05f5..5a788c0 100644 --- a/main/src/cgeo/geocaching/files/FileList.java +++ b/main/src/cgeo/geocaching/files/FileList.java @@ -2,6 +2,7 @@ package cgeo.geocaching.files; import cgeo.geocaching.R; import cgeo.geocaching.Settings; +import cgeo.geocaching.StoredList; import cgeo.geocaching.activity.AbstractListActivity; import org.apache.commons.collections.CollectionUtils; @@ -29,8 +30,7 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis private ProgressDialog waitDialog = null; private loadFiles searchingThread = null; private boolean endSearching = false; - private int listId = 1; - + private int listId = StoredList.STANDARD_LIST_ID; final private Handler changeWaitDialogHandler = new Handler() { private String searchInfo; @@ -105,8 +105,8 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis if (extras != null) { listId = extras.getInt("list"); } - if (listId <= 0) { - listId = 1; + if (listId <= StoredList.TEMPORARY_LIST_ID) { + listId = StoredList.STANDARD_LIST_ID; } setAdapter(); diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java index 8a4a8fc..836f6e8 100644 --- a/main/src/cgeo/geocaching/files/GPXImporter.java +++ b/main/src/cgeo/geocaching/files/GPXImporter.java @@ -7,6 +7,7 @@ import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.activity.Progress;
+import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.utils.CancellableHandler;
import org.apache.commons.lang3.StringUtils;
@@ -29,6 +30,7 @@ import java.io.InputStream; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.zip.ZipEntry;
@@ -138,7 +140,7 @@ public class GPXImporter { SearchResult search = storeParsedCaches(caches);
Log.i(Settings.tag, "Imported successfully " + caches.size() + " caches.");
- importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED, SearchResult.getCount(search), 0, search));
+ importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED, search.getCount(), 0, search));
} catch (IOException e) {
Log.i(Settings.tag, "Importing caches failed - error reading data: " + e.getMessage());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_io, 0, e.getLocalizedMessage()));
@@ -161,17 +163,15 @@ public class GPXImporter { final cgeoapplication app = cgeoapplication.getInstance();
int storedCaches = 0;
for (cgCache cache : caches) {
- // remove from cache because a cache might be re-imported
- cgeoapplication.removeCacheFromCache(cache.getGeocode());
- app.addCacheToSearch(search, cache);
-
- // save memory, imported caches are typically not used immediately
- cgeoapplication.removeCacheFromCache(cache.getGeocode());
+ search.addCache(cache);
+ if (app.saveCache(cache, EnumSet.of(SaveFlag.SAVEDB))) {
+ storedCaches++;
+ }
if (progressHandler.isCancelled()) {
throw new CancellationException();
}
- progressHandler.sendMessage(progressHandler.obtainMessage(0, ++storedCaches, 0));
+ progressHandler.sendMessage(progressHandler.obtainMessage(0, storedCaches, 0));
}
return search;
}
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java index 1082c9c..79e790c 100644 --- a/main/src/cgeo/geocaching/files/GPXParser.java +++ b/main/src/cgeo/geocaching/files/GPXParser.java @@ -2,6 +2,7 @@ package cgeo.geocaching.files; import cgeo.geocaching.R; import cgeo.geocaching.Settings; +import cgeo.geocaching.StoredList; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgLog; import cgeo.geocaching.cgTrackable; @@ -64,7 +65,7 @@ public abstract class GPXParser extends FileParser { private static final Pattern PATTERN_MILLISECONDS = Pattern.compile("\\.\\d{3,7}"); - private int listId = 1; + private int listId = StoredList.STANDARD_LIST_ID; final protected String namespace; final private String version; diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java index 7a8a674..ea4c824 100644 --- a/main/src/cgeo/geocaching/files/LocParser.java +++ b/main/src/cgeo/geocaching/files/LocParser.java @@ -1,11 +1,13 @@ package cgeo.geocaching.files; -import cgeo.geocaching.ParseResult; +import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgCoord; +import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.geopoint.GeopointParser; import cgeo.geocaching.utils.CancellableHandler; @@ -42,12 +44,13 @@ public final class LocParser extends FileParser { private int listId; - public static void parseLoc(final ParseResult parseResult, final String fileContent) { + public static void parseLoc(final SearchResult searchResult, final String fileContent) { final Map<String, cgCoord> cidCoords = parseCoordinates(fileContent); // save found cache coordinates - for (cgCache cache : parseResult.cacheList) { - if (cidCoords.containsKey(cache.getGeocode())) { + for (String geocode : searchResult.getGeocodes()) { + if (cidCoords.containsKey(geocode)) { + cgCache cache = cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOADCACHEORDB); cgCoord coord = cidCoords.get(cache.getGeocode()); copyCoordToCache(coord, cache); diff --git a/main/src/cgeo/geocaching/filter/AttributeFilter.java b/main/src/cgeo/geocaching/filter/AttributeFilter.java index ab4ada0..bdf4f71 100644 --- a/main/src/cgeo/geocaching/filter/AttributeFilter.java +++ b/main/src/cgeo/geocaching/filter/AttributeFilter.java @@ -3,11 +3,14 @@ package cgeo.geocaching.filter; import cgeo.geocaching.R; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.enumerations.LoadFlags.LoadFlag; import org.apache.commons.lang3.StringUtils; import android.content.res.Resources; +import java.util.EnumSet; + public class AttributeFilter extends AbstractFilter { private final String attribute; @@ -31,7 +34,7 @@ public class AttributeFilter extends AbstractFilter { @Override public boolean accepts(final cgCache cache) { - final cgCache fullCache = cgeoapplication.getInstance().getCacheByGeocode(cache.getGeocode()); + final cgCache fullCache = cgeoapplication.getInstance().loadCache(cache.getGeocode(), EnumSet.of(LoadFlag.LOADATTRIBUTES)); return fullCache.getAttributes().contains(attribute); } diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index 919aeff..62b0f09 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -1,9 +1,9 @@ package cgeo.geocaching.maps; -import cgeo.geocaching.ParseResult; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; +import cgeo.geocaching.StoredList; import cgeo.geocaching.UpdateDirectionCallback; import cgeo.geocaching.UpdateLocationCallback; import cgeo.geocaching.cgBase; @@ -16,6 +16,7 @@ import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.cgeocaches; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; @@ -114,7 +115,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory private WaypointType waypointTypeIntent = null; private int[] mapStateIntent = null; // status data - private ParseResult search = null; + private SearchResult search = null; private String token = null; private boolean noMapTokenShowed = false; // map status data @@ -689,12 +690,11 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory mapView.repaintRequired(overlayCaches); return true; case MENU_AS_LIST: { - final SearchResult search = new SearchResult(); + final SearchResult searchResult = new SearchResult(); search.totalCnt = caches.size(); for (cgCache cache : caches) { - search.addGeocode(cache.getGeocode()); + searchResult.addCache(cache); } - app.addSearch(caches, 0); cgeocaches.startActivityMap(activity, search); return true; } @@ -1136,19 +1136,17 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory return; } - //LeeB - I think this can be done better: - //1. fetch and draw(in another thread) caches from the db (fast? db read will be the slow bit) - //2. fetch and draw(in another thread) and then insert into the db caches from geocaching.com - dont draw/insert if exist in memory? - - // stage 1 - pull and render from the DB only + // stage 1 - pull and render from the DB only for live map if (fromDetailIntent || searchIntent != null) { - search = new ParseResult(searchIntent); + // map started from another activity + search = new SearchResult(searchIntent); } else { + // live map if (!live || !Settings.isLiveMap()) { - search = new ParseResult(app.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType())); + search = new SearchResult(app.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType())); } else { - search = new ParseResult(app.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType())); + search = new SearchResult(app.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType())); } } @@ -1163,7 +1161,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory return; } - caches = app.getCaches(search, true); + caches = search.getCachesFromSearchResult(LoadFlags.LOADWAYPOINTS); //if in live map and stored caches are found / disables are also shown. if (live && Settings.isLiveMap()) { @@ -1290,7 +1288,9 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory return; } - caches = app.getCaches(search, centerLat, centerLon, spanLat, spanLon); + if (search != null) { + caches = search.getCachesFromSearchResult(LoadFlags.LOADCACHEORDB); + } if (stop) { displayHandler.sendEmptyMessage(UPDATE_TITLE); @@ -1621,7 +1621,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory break; } - cgBase.storeCache(activity, null, geocode, 1, handler); + cgBase.storeCache(activity, null, geocode, StoredList.STANDARD_LIST_ID, handler); } } catch (Exception e) { Log.e(Settings.tag, "cgeocaches.LoadDetails.run: " + e.toString()); @@ -1680,7 +1680,9 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory if (geocodeCenter != null) { viewport = app.getBounds(geocodeCenter); } else { - viewport = app.getBounds(searchCenter); + if (searchCenter != null) { + viewport = app.getBounds(searchCenter.getGeocodes()); + } } if (viewport == null || viewport.size() < 5) { diff --git a/main/src/cgeo/geocaching/network/HtmlImage.java b/main/src/cgeo/geocaching/network/HtmlImage.java index 34f4f36..a643383 100644 --- a/main/src/cgeo/geocaching/network/HtmlImage.java +++ b/main/src/cgeo/geocaching/network/HtmlImage.java @@ -2,6 +2,7 @@ package cgeo.geocaching.network; import cgeo.geocaching.R; import cgeo.geocaching.Settings; +import cgeo.geocaching.StoredList; import cgeo.geocaching.cgBase; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.files.LocalStorage; @@ -193,7 +194,7 @@ public class HtmlImage implements Html.ImageGetter { private Bitmap loadCachedImage(final File file) { if (file.exists()) { - if (listId > 0 || file.lastModified() > (new Date().getTime() - (24 * 60 * 60 * 1000))) { + if (listId >= StoredList.STANDARD_LIST_ID || file.lastModified() > (new Date().getTime() - (24 * 60 * 60 * 1000))) { setSampleSize(file); return BitmapFactory.decodeFile(file.getPath(), bfOptions); } |