diff options
Diffstat (limited to 'mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/domain/Record.java')
-rw-r--r-- | mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/domain/Record.java | 308 |
1 files changed, 0 insertions, 308 deletions
diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/domain/Record.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/domain/Record.java deleted file mode 100644 index 145704c1c..000000000 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/domain/Record.java +++ /dev/null @@ -1,308 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.sync.repositories.domain; - -import java.io.UnsupportedEncodingException; - -import org.mozilla.gecko.sync.CryptoRecord; -import org.mozilla.gecko.sync.ExtendedJSONObject; - -/** - * Record is the abstract base class for all entries that Sync processes: - * bookmarks, passwords, history, and such. - * - * A Record can be initialized from or serialized to a CryptoRecord for - * submission to an encrypted store. - * - * Records should be considered to be conventionally immutable: modifications - * should be completed before the new record object escapes its constructing - * scope. Note that this is a critically important part of equality. As Rich - * Hickey notes: - * - * … the only things you can really compare for equality are immutable things, - * because if you compare two things for equality that are mutable, and ever - * say true, and they're ever not the same thing, you are wrong. Or you will - * become wrong at some point in the future. - * - * Records have a layered definition of equality. Two records can be said to be - * "equal" if: - * - * * They have the same GUID and collection. Two crypto/keys records are in some - * way "the same". - * This is `equalIdentifiers`. - * - * * Their most significant fields are the same. That is to say, they share a - * GUID, a collection, deletion, and domain-specific fields. Two copies of - * crypto/keys, neither deleted, with the same encrypted data but different - * modified times and sortIndex are in a stronger way "the same". - * This is `equalPayloads`. - * - * * Their most significant fields are the same, and their local fields (e.g., - * the androidID to which we have decided that this record maps) are congruent. - * A record with the same androidID, or one whose androidID has not been set, - * can be considered "the same". - * This concept can be extended by Record subclasses. The key point is that - * reconciling should be applied to the contents of these records. For example, - * two history records with the same URI and GUID, but different visit arrays, - * can be said to be congruent. - * This is `congruentWith`. - * - * * They are strictly identical. Every field that is persisted, including - * lastModified and androidID, is equal. - * This is `equals`. - * - * Different parts of the codebase have use for different layers of this - * comparison hierarchy. For instance, lastModified times change every time a - * record is stored; a store followed by a retrieval will return a Record that - * shares its most significant fields with the input, but has a later - * lastModified time and might not yet have values set for others. Reconciling - * will thus ignore the modification time of a record. - * - * @author rnewman - * - */ -public abstract class Record { - - public String guid; - public String collection; - public long lastModified; - public boolean deleted; - public long androidID; - /** - * An integer indicating the relative importance of this item in the collection. - * <p> - * Default is 0. - */ - public long sortIndex; - /** - * The number of seconds to keep this record. After that time this item will - * no longer be returned in response to any request, and it may be pruned from - * the database. - * <p> - * Negative values mean never forget this record. - * <p> - * Default is 1 year. - */ - public long ttl; - - public Record(String guid, String collection, long lastModified, boolean deleted) { - this.guid = guid; - this.collection = collection; - this.lastModified = lastModified; - this.deleted = deleted; - this.sortIndex = 0; - this.ttl = 365 * 24 * 60 * 60; // Seconds. - this.androidID = -1; - } - - /** - * Return true iff the input is a Record and has the same - * collection and guid as this object. - */ - public boolean equalIdentifiers(Object o) { - if (!(o instanceof Record)) { - return false; - } - - Record other = (Record) o; - if (this.guid == null) { - if (other.guid != null) { - return false; - } - } else { - if (!this.guid.equals(other.guid)) { - return false; - } - } - if (this.collection == null) { - if (other.collection != null) { - return false; - } - } else { - if (!this.collection.equals(other.collection)) { - return false; - } - } - return true; - } - - /** - * @param o - * The object to which this object should be compared. - * @return - * true iff the input is a Record which is substantially the - * same as this object. - */ - public boolean equalPayloads(Object o) { - if (!this.equalIdentifiers(o)) { - return false; - } - Record other = (Record) o; - return this.deleted == other.deleted; - } - - /** - * - * - * @param o - * The object to which this object should be compared. - * @return - * true iff the input is a Record which is substantially the - * same as this object, considering the ability and desire to - * reconcile the two objects if possible. - */ - public boolean congruentWith(Object o) { - if (!this.equalIdentifiers(o)) { - return false; - } - Record other = (Record) o; - return congruentAndroidIDs(other) && - (this.deleted == other.deleted); - } - - public boolean congruentAndroidIDs(Record other) { - // We treat -1 as "unset", and treat this as - // congruent with any other value. - if (this.androidID != -1 && - other.androidID != -1 && - this.androidID != other.androidID) { - return false; - } - return true; - } - - /** - * Return true iff the input is both equal in terms of payload, - * and also shares transient values such as timestamps. - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof Record)) { - return false; - } - - Record other = (Record) o; - return equalTimestamps(other) && - equalSortIndices(other) && - equalAndroidIDs(other) && - equalPayloads(o); - } - - public boolean equalAndroidIDs(Record other) { - return this.androidID == other.androidID; - } - - public boolean equalSortIndices(Record other) { - return this.sortIndex == other.sortIndex; - } - - public boolean equalTimestamps(Object o) { - if (!(o instanceof Record)) { - return false; - } - return ((Record) o).lastModified == this.lastModified; - } - - protected abstract void populatePayload(ExtendedJSONObject payload); - protected abstract void initFromPayload(ExtendedJSONObject payload); - - public void initFromEnvelope(CryptoRecord envelope) { - ExtendedJSONObject p = envelope.payload; - this.guid = envelope.guid; - checkGUIDs(p); - - this.collection = envelope.collection; - this.lastModified = envelope.lastModified; - - final Object del = p.get("deleted"); - if (del instanceof Boolean) { - this.deleted = (Boolean) del; - } else { - this.initFromPayload(p); - } - - } - - public CryptoRecord getEnvelope() { - CryptoRecord rec = new CryptoRecord(this); - ExtendedJSONObject payload = new ExtendedJSONObject(); - payload.put("id", this.guid); - - if (this.deleted) { - payload.put("deleted", true); - } else { - populatePayload(payload); - } - rec.payload = payload; - return rec; - } - - @SuppressWarnings("static-method") - public String toJSONString() { - throw new RuntimeException("Cannot JSONify non-CryptoRecord Records."); - } - - public byte[] toJSONBytes() { - try { - return this.toJSONString().getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - // Can't happen. - return null; - } - } - - /** - * Utility for safely populating an output CryptoRecord. - * - * @param rec - * @param key - * @param value - */ - @SuppressWarnings("static-method") - protected void putPayload(CryptoRecord rec, String key, String value) { - if (value == null) { - return; - } - rec.payload.put(key, value); - } - - protected void putPayload(ExtendedJSONObject payload, String key, String value) { - this.putPayload(payload, key, value, false); - } - - @SuppressWarnings("static-method") - protected void putPayload(ExtendedJSONObject payload, String key, String value, boolean excludeEmpty) { - if (value == null) { - return; - } - if (excludeEmpty && value.equals("")) { - return; - } - payload.put(key, value); - } - - protected void checkGUIDs(ExtendedJSONObject payload) { - String payloadGUID = (String) payload.get("id"); - if (this.guid == null || - payloadGUID == null) { - String detailMessage = "Inconsistency: either envelope or payload GUID missing."; - throw new IllegalStateException(detailMessage); - } - if (!this.guid.equals(payloadGUID)) { - String detailMessage = "Inconsistency: record has envelope ID " + this.guid + ", payload ID " + payloadGUID; - throw new IllegalStateException(detailMessage); - } - } - - /** - * Oh for persistent data structures. - * - * @param guid - * @param androidID - * @return - * An identical copy of this record with the provided two values. - */ - public abstract Record copyWithIDs(String guid, long androidID); -} |