/**
   * Gets the followers of a following specified by the given following id and follow type.
   *
   * @param followingId the given following id
   * @param followingType the specified following type
   * @param currentPageNum the specified current page number
   * @param pageSize the specified page size
   * @return result json object, for example,
   *     <pre>
   * {
   *     "paginationRecordCount": int,
   *     "rslts": java.util.List[{
   *         "oId": "",
   *         "followerId": "",
   *         "followingId": "",
   *         "followingType": int
   *     }, ....]
   * }
   * </pre>
   *
   * @throws RepositoryException repository exception
   */
  private JSONObject getFollowers(
      final String followingId,
      final int followingType,
      final int currentPageNum,
      final int pageSize)
      throws RepositoryException {
    final List<Filter> filters = new ArrayList<Filter>();
    filters.add(new PropertyFilter(Follow.FOLLOWING_ID, FilterOperator.EQUAL, followingId));
    filters.add(new PropertyFilter(Follow.FOLLOWING_TYPE, FilterOperator.EQUAL, followingType));

    final Query query =
        new Query()
            .addSort(Keys.OBJECT_ID, SortDirection.DESCENDING)
            .setFilter(new CompositeFilter(CompositeFilterOperator.AND, filters))
            .setPageSize(pageSize)
            .setCurrentPageNum(currentPageNum);

    final JSONObject result = followRepository.get(query);

    final List<JSONObject> records =
        CollectionUtils.<JSONObject>jsonArrayToList(result.optJSONArray(Keys.RESULTS));
    final int recordCnt =
        result.optJSONObject(Pagination.PAGINATION).optInt(Pagination.PAGINATION_RECORD_COUNT);

    final JSONObject ret = new JSONObject();
    ret.put(Keys.RESULTS, (Object) records);
    ret.put(Pagination.PAGINATION_RECORD_COUNT, recordCnt);

    return ret;
  }
  /**
   * Determines whether exists a follow relationship for the specified follower and the specified
   * following entity.
   *
   * @param followerId the specified follower id
   * @param followingId the specified following entity id
   * @return {@code true} if exists, returns {@code false} otherwise
   */
  public boolean isFollowing(final String followerId, final String followingId) {
    try {
      return followRepository.exists(followerId, followingId);
    } catch (final RepositoryException e) {
      LOGGER.log(
          Level.ERROR,
          "Determines following failed[followerId="
              + followerId
              + ", followingId="
              + followingId
              + ']',
          e);

      return false;
    }
  }
  /**
   * Gets the follower count of a following specified by the given following id and following type.
   *
   * @param followingId the given following id
   * @param followingType the given following type
   * @return count
   */
  public long getFollowerCount(final String followingId, final int followingType) {
    final List<Filter> filters = new ArrayList<Filter>();
    filters.add(new PropertyFilter(Follow.FOLLOWING_ID, FilterOperator.EQUAL, followingId));
    filters.add(new PropertyFilter(Follow.FOLLOWING_TYPE, FilterOperator.EQUAL, followingType));

    final Query query =
        new Query().setFilter(new CompositeFilter(CompositeFilterOperator.AND, filters));

    try {
      return followRepository.count(query);
    } catch (final RepositoryException e) {
      LOGGER.log(Level.ERROR, "Counts follower count error", e);

      return 0;
    }
  }