All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.parse.PushHistory Maven / Gradle / Ivy

Go to download

A library that gives you access to the powerful Parse cloud platform from your Android app.

There is a newer version: 1.17.3
Show newest version
/*
 * Copyright (c) 2015-present, Parse, LLC.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
package com.parse;

import java.util.HashSet;
import java.util.Iterator;
import java.util.PriorityQueue;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * PushHistory manages a fixed-length history of pushes received. It is used by to dedup recently
 * received messages, as well as keep track of a last received timestamp that is included in PPNS
 * handshakes.
 */
/** package */ class PushHistory {
  private static final String TAG = "com.parse.PushHistory";
  
  private static class Entry implements Comparable {
    public String pushId;
    public String timestamp;
    
    public Entry(String pushId, String timestamp) {
      this.pushId = pushId;
      this.timestamp = timestamp;
    }
    
    @Override
    public int compareTo(Entry other) {
      return timestamp.compareTo(other.timestamp);
    }
  }
  
  private final int maxHistoryLength;
  private final PriorityQueue entries;
  private final HashSet pushIds;
  private String lastTime;
  
  /**
   * Creates a push history object from a JSON object that looks like this:
   * 
   * {
   *    "seen": {
   *        "push_id_1": "2013-11-01T22:01:00.000Z",
   *        "push_id_2": "2013-11-01T22:01:01.000Z",
   *        "push_id_3": "2013-11-01T22:01:02.000Z"
   *    },
   *    "lastTime": "2013-11-01T22:01:02.000Z"
   * }
   * 
   * The "history" entries correspond to entries in the "entries" queue.
   * The "lastTime" entry corresponds to the "lastTime" field.
   */
  public PushHistory(int maxHistoryLength, JSONObject json) {
    this.maxHistoryLength = maxHistoryLength;
    this.entries = new PriorityQueue(maxHistoryLength + 1);
    this.pushIds = new HashSet(maxHistoryLength + 1);
    this.lastTime = null;
    
    if (json != null) {
      JSONObject jsonHistory = json.optJSONObject("seen");
      if (jsonHistory != null) {
        Iterator it = jsonHistory.keys();
        while (it.hasNext()) {
          String pushId = (String)it.next();
          String timestamp = jsonHistory.optString(pushId, null);
          
          if (pushId != null && timestamp != null) {
            tryInsertPush(pushId, timestamp);
          }
        }
      }
      setLastReceivedTimestamp(json.optString("lastTime", null));
    }
  }
  
  /**
   * Serializes the history state to a JSON object using the format described in loadJSON().
   */
  public JSONObject toJSON() throws JSONException {
    JSONObject json = new JSONObject();

    if (entries.size() > 0) {
      JSONObject history = new JSONObject();
      for (Entry e : entries) {
        history.put(e.pushId, e.timestamp);
      }
      json.put("seen", history);
    }

    json.putOpt("lastTime", lastTime);

    return json;
  }

  /**
   * Returns the last received timestamp, which is always updated whether or not a push was
   * successfully inserted into history.
   */
  public String getLastReceivedTimestamp() {
    return lastTime;
  }
  
  public void setLastReceivedTimestamp(String lastTime) {
    this.lastTime = lastTime;
  }

  /**
   * Attempts to insert a push into history. The push is ignored if we have already seen it
   * recently. Otherwise, the push is inserted into history. If the length of the history exceeds
   * the maximum length, then the history is trimmed by removing the oldest pushes until it no
   * longer exceeds the maximum length.
   * 
   * @return Returns whether or not the push was inserted into history.  
   */
  public boolean tryInsertPush(String pushId, String timestamp) {
    if (timestamp == null) {
      throw new IllegalArgumentException("Can't insert null pushId or timestamp into history");
    }
    
    if (lastTime == null || timestamp.compareTo(lastTime) > 0) {
      lastTime = timestamp;
    }

    if (pushIds.contains(pushId)) {
      PLog.e(TAG, "Ignored duplicate push " + pushId);
      return false;
    }

    entries.add(new Entry(pushId, timestamp));
    pushIds.add(pushId);

    while (entries.size() > maxHistoryLength) {
      Entry head = entries.remove();
      pushIds.remove(head.pushId);
    }
    
    return true;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy