protected List handleGet()

in server/core/src/main/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandler.java [70:166]


    protected List<Stanza> handleGet(IQStanza stanza, ServerRuntimeContext serverRuntimeContext,
            SessionContext sessionContext, StanzaBroker stanzaBroker) {
        ServiceCollector serviceCollector = null;

        // TODO if the target entity does not exist, return error/cancel/item-not-found
        // TODO more strictly, server can also return error/cancel/service-unavailable

        // retrieve the service collector
        try {
            serviceCollector = (ServiceCollector) serverRuntimeContext.getServerRuntimeContextService(
                    ServiceDiscoveryRequestListenerRegistry.SERVICE_DISCOVERY_REQUEST_LISTENER_REGISTRY);
        } catch (Exception e) {
            logger.error("error retrieving ServiceCollector service {}", e);
            serviceCollector = null;
        }

        if (serviceCollector == null) {
            return Collections.singletonList(
                    ServerErrorResponses.getStanzaError(StanzaErrorCondition.INTERNAL_SERVER_ERROR, stanza,
                            StanzaErrorType.CANCEL, "cannot retrieve IQ-get-info result from internal components",
                            getErrorLanguage(serverRuntimeContext, sessionContext), null));
        }

        // if "vysper.org" is the server entity, 'to' can either be "vysper.org",
        // "node@vysper.org", "service.vysper.org".
        Entity to = stanza.getTo();
        boolean isServerInfoRequest = false;
        boolean isComponentInfoRequest = false;
        Entity serverEntity = serverRuntimeContext.getServerEntity();
        if (to == null || to.equals(serverEntity)) {
            isServerInfoRequest = true; // this can only be meant to query the server
        } else if (serverRuntimeContext.hasComponentStanzaProcessor(to)) {
            isComponentInfoRequest = true; // this is a query to a component
        } else if (!to.isNodeSet()) {
            isServerInfoRequest = serverEntity.equals(to);
            if (!isServerInfoRequest) {
                return Collections.singletonList(ServerErrorResponses.getStanzaError(
                        StanzaErrorCondition.ITEM_NOT_FOUND, stanza, StanzaErrorType.CANCEL,
                        "server does not handle info query requests for " + to.getFullQualifiedName(),
                        getErrorLanguage(serverRuntimeContext, sessionContext), null));
            }
        }

        XMLElement queryElement = stanza.getFirstInnerElement();
        String node = queryElement != null ? queryElement.getAttributeValue("node") : null;

        // collect all the info response elements
        List<InfoElement> elements = null;
        try {
            Entity from = stanza.getFrom();
            if (from == null)
                from = sessionContext.getInitiatingEntity();
            if (isServerInfoRequest) {
                elements = serviceCollector.processServerInfoRequest(new InfoRequest(from, to, node, stanza.getID()));
            } else if (isComponentInfoRequest) {
                elements = serviceCollector
                        .processComponentInfoRequest(new InfoRequest(from, to, node, stanza.getID()), stanzaBroker);
            } else {
                // "When an entity sends a disco#info request to a bare JID
                // (<account@domain.tld>) hosted by a server,
                // the server itself MUST reply on behalf of the hosted account, either with an
                // IQ-error or an IQ-result"
                if (to.isResourceSet()) {
                    relayOrWrite(stanza, sessionContext, stanzaBroker);
                    return Collections.emptyList();
                } else {
                    elements = serviceCollector.processInfoRequest(new InfoRequest(from, to, node, stanza.getID()));
                }
            }
        } catch (ServiceDiscoveryRequestException e) {
            // the request yields an error
            StanzaErrorCondition stanzaErrorCondition = e.getErrorCondition();
            if (stanzaErrorCondition == null)
                stanzaErrorCondition = StanzaErrorCondition.INTERNAL_SERVER_ERROR;
            return Collections.singletonList(ServerErrorResponses.getStanzaError(stanzaErrorCondition, stanza,
                    StanzaErrorType.CANCEL, "disco info request failed.",
                    getErrorLanguage(serverRuntimeContext, sessionContext), null));
        }

        // TODO check that elementSet contains at least one identity element and on
        // feature element!

        // render the stanza with information collected
        StanzaBuilder stanzaBuilder = StanzaBuilder
                .createIQStanza(to, stanza.getFrom(), IQStanzaType.RESULT, stanza.getID())
                .startInnerElement("query", NamespaceURIs.XEP0030_SERVICE_DISCOVERY_INFO);
        if (node != null) {
            stanzaBuilder.addAttribute("node", node);
        }
        for (InfoElement infoElement : elements) {
            infoElement.insertElement(stanzaBuilder);
        }

        stanzaBuilder.endInnerElement();

        return Collections.singletonList(stanzaBuilder.build());
    }