summaryrefslogtreecommitdiffstats
path: root/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/domain/Record.java
diff options
context:
space:
mode:
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.java308
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);
-}