michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0:
michael@0: package org.mozilla.gecko.sync;
michael@0:
michael@0: import java.util.Collections;
michael@0: import java.util.HashMap;
michael@0: import java.util.Map;
michael@0: import java.util.Map.Entry;
michael@0:
michael@0: import org.mozilla.gecko.background.common.log.Logger;
michael@0:
michael@0: /**
michael@0: * Fetches the timestamp information in info/collections
on the
michael@0: * Sync server. Provides access to those timestamps, along with logic to check
michael@0: * for whether a collection requires an update.
michael@0: */
michael@0: public class InfoCollections {
michael@0: private static final String LOG_TAG = "InfoCollections";
michael@0:
michael@0: /**
michael@0: * Fields fetched from the server, or null
if not yet fetched.
michael@0: *
michael@0: * Rather than storing decimal/double timestamps, as provided by the server,
michael@0: * we convert immediately to milliseconds since epoch.
michael@0: */
michael@0: final Map timestamps;
michael@0:
michael@0: public InfoCollections() {
michael@0: this(new ExtendedJSONObject());
michael@0: }
michael@0:
michael@0: public InfoCollections(final ExtendedJSONObject record) {
michael@0: Logger.debug(LOG_TAG, "info/collections is " + record.toJSONString());
michael@0: HashMap map = new HashMap();
michael@0:
michael@0: for (Entry entry : record.entrySet()) {
michael@0: final String key = entry.getKey();
michael@0: final Object value = entry.getValue();
michael@0:
michael@0: // These objects are most likely going to be Doubles. Regardless, we
michael@0: // want to get them in a more sane time format.
michael@0: if (value instanceof Double) {
michael@0: map.put(key, Utils.decimalSecondsToMilliseconds((Double) value));
michael@0: continue;
michael@0: }
michael@0: if (value instanceof Long) {
michael@0: map.put(key, Utils.decimalSecondsToMilliseconds((Long) value));
michael@0: continue;
michael@0: }
michael@0: if (value instanceof Integer) {
michael@0: map.put(key, Utils.decimalSecondsToMilliseconds((Integer) value));
michael@0: continue;
michael@0: }
michael@0: Logger.warn(LOG_TAG, "Skipping info/collections entry for " + key);
michael@0: }
michael@0:
michael@0: this.timestamps = Collections.unmodifiableMap(map);
michael@0: }
michael@0:
michael@0: /**
michael@0: * Return the timestamp for the given collection, or null if the timestamps
michael@0: * have not been fetched or the given collection does not have a timestamp.
michael@0: *
michael@0: * @param collection
michael@0: * The collection to inspect.
michael@0: * @return the timestamp in milliseconds since epoch.
michael@0: */
michael@0: public Long getTimestamp(String collection) {
michael@0: if (timestamps == null) {
michael@0: return null;
michael@0: }
michael@0: return timestamps.get(collection);
michael@0: }
michael@0:
michael@0: /**
michael@0: * Test if a given collection needs to be updated.
michael@0: *
michael@0: * @param collection
michael@0: * The collection to test.
michael@0: * @param lastModified
michael@0: * Timestamp when local record was last modified.
michael@0: */
michael@0: public boolean updateNeeded(String collection, long lastModified) {
michael@0: Logger.trace(LOG_TAG, "Testing " + collection + " for updateNeeded. Local last modified is " + lastModified + ".");
michael@0:
michael@0: // No local record of modification time? Need an update.
michael@0: if (lastModified <= 0) {
michael@0: return true;
michael@0: }
michael@0:
michael@0: // No meta/global on the server? We need an update. The server fetch will fail and
michael@0: // then we will upload a fresh meta/global.
michael@0: Long serverLastModified = getTimestamp(collection);
michael@0: if (serverLastModified == null) {
michael@0: return true;
michael@0: }
michael@0:
michael@0: // Otherwise, we need an update if our modification time is stale.
michael@0: return (serverLastModified.longValue() > lastModified);
michael@0: }
michael@0: }