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

cn.leancloud.livequery.AVLiveQuery Maven / Gradle / Ivy

There is a newer version: 8.2.28
Show newest version
package cn.leancloud.livequery;

import cn.leancloud.AVException;
import cn.leancloud.AVLogger;
import cn.leancloud.AVQuery;
import cn.leancloud.AVUser;
import cn.leancloud.codec.MD5;
import cn.leancloud.core.AppConfiguration;
import cn.leancloud.im.InternalConfiguration;
import cn.leancloud.ops.Utils;
import cn.leancloud.service.RealtimeClient;
import cn.leancloud.session.AVConnectionManager;
import cn.leancloud.session.AVDefaultConnectionListener;
import cn.leancloud.session.AVSessionManager;
import cn.leancloud.utils.AVUtils;
import cn.leancloud.utils.LogUtil;
import cn.leancloud.utils.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

import java.util.*;

public class AVLiveQuery {
  private static final AVLogger LOGGER = LogUtil.getLogger(AVLiveQuery.class);
  private static final String SP_LIVEQUERY_KEY = "livequery_keyzone";
  private static final String SP_SUBSCRIBE_ID = "subscribeId";
  private static final String QUERY_ID = "query_id";
  private static final String SESSION_TOKEN = "sessionToken";
  private static final String QUERY = "query";
  private static final String OBJECT = "object";
  private static final String OP = "op";
  private static final String UPDATE_KEYS = "updatedKeys";

  public static final String SUBSCRIBE_ID = "id";
  public static final String LIVEQUERY_PRIFIX = "live_query_";
  public static final String ACTION_LIVE_QUERY_LOGIN = "action_live_query_login";

  public enum EventType {
    CREATE("create"), UPDATE("update"), ENTER("enter"), LEAVE("leave"), DELETE("delete"), LOGIN("login"), UNKONWN("unknown");

    private String event;

    public static EventType getType(String event) {
      if (CREATE.getContent().equals(event)) {
        return CREATE;
      } else if (UPDATE.getContent().equals(event)) {
        return UPDATE;
      } else if (ENTER.getContent().equals(event)) {
        return ENTER;
      } else if (LEAVE.getContent().equals(event)) {
        return LEAVE;
      } else if (DELETE.getContent().equals(event)) {
        return DELETE;
      } else if (LOGIN.getContent().equals(event)) {
        return LOGIN;
      }
      return UNKONWN;
    }

    EventType(String event) {
      this.event = event;
    }

    public String getContent() {
      return event;
    }
  }

  public static void processData(ArrayList dataList) {
    for (final String data : dataList) {
      try {
        JSONObject jsonObject = JSON.parseObject(data);
        String op = jsonObject.getString(OP);
        String queryId = jsonObject.getString(QUERY_ID);
        JSONObject object = jsonObject.getJSONObject(OBJECT);
        if (!StringUtil.isEmpty(queryId)) {
          ArrayList updateKeyList = new ArrayList();
          if (jsonObject.containsKey(UPDATE_KEYS)) {
            JSONArray jsonArray = jsonObject.getJSONArray(UPDATE_KEYS);
            for (Object item : jsonArray) {
              updateKeyList.add((String)item);
            }
          }

          for (AVLiveQuery liveQuery : liveQuerySet) {
            if (queryId.equals(liveQuery.queryId) && null != liveQuery.eventHandler) {
              liveQuery.eventHandler.done(EventType.getType(op), Utils.parseObjectFromMap(object), updateKeyList);
            }
          }
        }
      } catch (Exception e) {
        LOGGER.e("Parsing json data error, ", e);
      }
    };
  }

  private static Set liveQuerySet = Collections.synchronizedSet(new HashSet());

  static void resumeSubscribeers() {
    for (AVLiveQuery query: liveQuerySet) {
      query.subscribeInBackground(null);
    }
  }

  static {
    AVConnectionManager.getInstance().subscribeConnectionListener(LiveQueryOperationDelegate.LIVEQUERY_DEFAULT_ID,
            new LiveQueryConnectionListener());
  }

  private static String subscribeId;
  private String queryId;
  private AVQuery query;
  private AVLiveQueryEventHandler eventHandler;

  private AVLiveQuery(AVQuery query) {
    this.query = query;
  }
  /**
   * initialize AVLiveQuery with AVQuery
   * @param query
   * @return
   */
  public static AVLiveQuery initWithQuery(AVQuery query) {
    if (null == query) {
      throw new IllegalArgumentException("query cannot be null");
    }
    return new AVLiveQuery(query);
  }

  /**
   * subscribe the query
   * @param callback
   */
  public void subscribeInBackground(final AVLiveQuerySubscribeCallback callback) {
    Map params = query.assembleParameters();
    params.put("className", query.getClassName());

    Map dataMap = new HashMap<>();
    dataMap.put(QUERY, params);
    String session = getSessionToken();
    if (!StringUtil.isEmpty(session)) {
      dataMap.put(SESSION_TOKEN, session);
    }

    dataMap.put(SUBSCRIBE_ID, getSubscribeId());

    RealtimeClient.getInstance().subscribeLiveQuery(dataMap).subscribe(new Observer() {
      @Override
      public void onSubscribe(Disposable disposable) {

      }

      @Override
      public void onNext(JSONObject jsonObject) {
        if (null != jsonObject && jsonObject.containsKey(QUERY_ID)) {
          queryId = jsonObject.getString(QUERY_ID);
          liveQuerySet.add(AVLiveQuery.this);
          loginLiveQuery(callback);
        } else if (null != callback) {
          callback.internalDone(new AVException(AVException.UNKNOWN, "response isn't recognized"));
        }
      }

      @Override
      public void onError(Throwable throwable) {
        if (null != callback) {
          callback.internalDone(new AVException(throwable));
        }
      }

      @Override
      public void onComplete() {

      }
    });
  }

  public void setEventHandler(AVLiveQueryEventHandler eventHandler) {
    if (null == eventHandler) {
      throw new IllegalArgumentException("eventHandler can not be null.");
    }
    this.eventHandler = eventHandler;
  }

  private void loginLiveQuery(final AVLiveQuerySubscribeCallback callback) {
    boolean ret = InternalConfiguration.getOperationTube().loginLiveQuery(getSubscribeId(), callback);
    if (!ret && null != callback) {
      callback.internalDone(new AVException(AVException.OPERATION_FORBIDDEN, "can't invoke operation in background."));
    }
  }

  /**
   * unsubscribe the query
   * @param callback
   */
  public void unsubscribeInBackground(final AVLiveQuerySubscribeCallback callback) {
    Map map = new HashMap<>();
    map.put(SUBSCRIBE_ID, getSubscribeId());
    map.put(QUERY_ID, queryId);

    RealtimeClient.getInstance().unsubscribeLiveQuery(map).subscribe(new Observer() {
      @Override
      public void onSubscribe(Disposable disposable) {
      }

      @Override
      public void onNext(JSONObject jsonObject) {
        liveQuerySet.remove(AVLiveQuery.this);
        queryId = "";
        if (null != callback) {
          callback.internalDone(null);
        }
      }

      @Override
      public void onError(Throwable throwable) {
        if (null != callback) {
          callback.internalDone(new AVException(throwable));
        }
      }

      @Override
      public void onComplete() {
      }
    });
  }

  private String getSubscribeId() {
    if (StringUtil.isEmpty(subscribeId)) {
      subscribeId = AppConfiguration.getDefaultSetting().getString(SP_LIVEQUERY_KEY,SP_SUBSCRIBE_ID, "");
      if (StringUtil.isEmpty(subscribeId)) {
        String packageName = AppConfiguration.getApplicationPackagename();
        String additionalStr = UUID.randomUUID().toString();
        subscribeId = MD5.computeMD5(packageName + additionalStr);
        AppConfiguration.getDefaultSetting().saveString(SP_LIVEQUERY_KEY, SP_SUBSCRIBE_ID, subscribeId);
      }
    }
    return subscribeId;
  }

  private String getSessionToken() {
    AVUser currentUser = AVUser.getCurrentUser();
    if (null != currentUser) {
      return currentUser.getSessionToken();
    }
    return "";
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy