discoInfoQuery method

Future<Result<StanzaError, DiscoInfo>> discoInfoQuery(
  1. JID entity,
  2. {String? node,
  3. bool shouldEncrypt = false,
  4. bool shouldCache = true}
)

Send a disco#info query to entity. If node is specified, then the disco#info request will be directed against that one node of entity.

shouldEncrypt indicates to possible end-to-end encryption implementations whether the request should be encrypted (true) or not (false).

shouldCache indicates whether the successful result of the disco#info query should be cached (true) or not(false).

Implementation

Future<Result<StanzaError, DiscoInfo>> discoInfoQuery(
  JID entity, {
  String? node,
  bool shouldEncrypt = false,
  bool shouldCache = true,
}) async {
  DiscoInfo? info;
  final cacheKey = DiscoCacheKey(entity, node);
  final ecm = getAttributes()
      .getManagerById<EntityCapabilitiesManager>(entityCapabilitiesManager);
  final ffuture = await _cacheLock
      .synchronized<Future<Future<Result<StanzaError, DiscoInfo>>?>?>(
          () async {
    // Check if we already know what the JID supports
    if (_discoInfoCache.containsKey(cacheKey)) {
      info = _discoInfoCache[cacheKey];
      return null;
    } else {
      // Check if we know entity capabilities
      if (ecm != null && node == null) {
        info = await ecm.getCachedDiscoInfoFromJid(entity);
        if (info != null) {
          return null;
        }
      }

      return _discoInfoTracker.waitFor(cacheKey);
    }
  });

  if (info != null) {
    return Result<DiscoError, DiscoInfo>(info);
  } else {
    final future = await ffuture;
    if (future != null) {
      return future;
    }
  }

  final stanza = (await getAttributes().sendStanza(
    StanzaDetails(
      buildDiscoInfoQueryStanza(entity, node),
      shouldEncrypt: shouldEncrypt,
    ),
  ))!;

  // Error handling
  if (stanza.attributes['type'] == 'error') {
    final result =
        Result<StanzaError, DiscoInfo>(StanzaError.fromXMLNode(stanza));
    await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache);
    return result;
  }

  final query = stanza.firstTag('query');
  if (query == null) {
    final result = Result<DiscoError, DiscoInfo>(InvalidResponseDiscoError());
    await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache);
    return result;
  }

  final result = Result<DiscoError, DiscoInfo>(
    DiscoInfo.fromQuery(
      query,
      entity,
    ),
  );
  await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache);
  return result;
}