public void execute()

in server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/StreamStartHandler.java [63:192]


    public void execute(Stanza stanza, ServerRuntimeContext serverRuntimeContext, boolean isOutboundStanza,
            SessionContext sessionContext, SessionStateHolder sessionStateHolder, StanzaBroker stanzaBroker) {
        XMLElementVerifier xmlElementVerifier = stanza.getVerifier();
        boolean jabberNamespace = NamespaceURIs.HTTP_ETHERX_JABBER_ORG_STREAMS.equals(stanza.getNamespaceURI());

        boolean clientCall = xmlElementVerifier.namespacePresent(NamespaceURIs.JABBER_CLIENT);
        boolean serverCall = xmlElementVerifier.namespacePresent(NamespaceURIs.JABBER_SERVER);

        // TODO is it better to derive c2s or s2s from the type of endpoint and verify
        // the namespace here?
        if (clientCall && serverCall)
            serverCall = false; // silently ignore ambiguous attributes
        if (serverCall)
            sessionContext.setServerToServer();
        else
            sessionContext.setClientToServer();

        if (sessionStateHolder.getState() != SessionState.INITIATED
                && sessionStateHolder.getState() != SessionState.ENCRYPTED
                && sessionStateHolder.getState() != SessionState.AUTHENTICATED) {
            stanzaBroker.writeToSession(buildUnsupportedStanzaType("unexpected stream start"));
            return;
        }

        // http://etherx.jabber.org/streams cannot be omitted
        if (!jabberNamespace) {
            stanzaBroker.writeToSession(buildIllegalNamespaceError(
                    "namespace is mandatory: " + NamespaceURIs.HTTP_ETHERX_JABBER_ORG_STREAMS));
            return;
        }

        // processing xml:lang
        String xmlLang = stanza.getXMLLang();
        sessionContext.setXMLLang(xmlLang);

        // processing version
        XMPPVersion responseVersion = null;
        // if version is not present, version "0.0" is assumed, represented by NULL.
        String versionAttributeValue = stanza.getAttributeValue("version");
        if (versionAttributeValue != null) {
            XMPPVersion clientVersion;
            try {
                clientVersion = new XMPPVersion(versionAttributeValue);
            } catch (IllegalArgumentException e) {
                // version string does not conform to spec
                stanzaBroker.writeToSession(
                        buildUnsupportedVersionError(xmlLang, versionAttributeValue, "illegal version value: "));
                return;
            }
            // check if version is supported
            if (!clientVersion.equals(XMPPVersion.VERSION_1_0)) {
                if (clientVersion.getMajor() == XMPPVersion.VERSION_1_0.getMajor()) {
                    // we live with the higher minor version, but only support ours
                    responseVersion = XMPPVersion.VERSION_1_0;
                } else {
                    // we do not support major changes, as of RFC3920
                    stanzaBroker.writeToSession(buildUnsupportedVersionError(xmlLang, versionAttributeValue,
                            "major version change not supported: "));
                    return;
                }
            } else {
                responseVersion = clientVersion;
            }
        }

        if (xmlElementVerifier.attributePresent("id")) {
            // ignore silently (see RFC3920 4.4)
        }

        Stanza responseStanza = null;
        if (clientCall) {
            // RFC3920: 'to' attribute SHOULD be used by the initiating entity
            String toValue = stanza.getAttributeValue("to");
            if (toValue != null) {
                try {
                    EntityImpl.parse(toValue);
                } catch (EntityFormatException e) {
                    stanzaBroker.writeToSession(ServerErrorResponses.getStreamError(
                            StreamErrorCondition.IMPROPER_ADDRESSING, sessionContext.getXMLLang(),
                            "could not parse incoming stanza's TO attribute", null));
                    return;
                }
                // TODO check if toEntity is served by this server
                // if (!server.doesServe(toEntity)) throw WhateverException();

                // TODO RFC3920: 'from' attribute SHOULD be silently ignored by the receiving
                // entity
                // TODO RFC3920bis: 'from' attribute SHOULD be not ignored by the receiving
                // entity and used as 'to' in responses
            }
            responseStanza = new ServerResponses().getStreamOpenerForClient(sessionContext.getServerJID(),
                    responseVersion, sessionContext);
        } else if (serverCall) {
            // RFC3920: 'from' attribute SHOULD be used by the receiving entity
            String fromValue = stanza.getAttributeValue("from");
            if (fromValue != null) {
                try {
                    EntityImpl.parse(fromValue);
                } catch (EntityFormatException e) {
                    stanzaBroker.writeToSession(ServerErrorResponses.getStreamError(StreamErrorCondition.INVALID_FROM,
                            sessionContext.getXMLLang(), "could not parse incoming stanza's FROM attribute", null));
                    return;
                }
            }

            responseStanza = new ServerResponses().getStreamOpenerForServerAcceptor(sessionContext.getServerJID(),
                    responseVersion, sessionContext, serverRuntimeContext.getSslContext() != null);
        } else {
            String descriptiveText = "one of the two namespaces must be present: " + NamespaceURIs.JABBER_CLIENT
                    + " or " + NamespaceURIs.JABBER_SERVER;
            stanzaBroker.writeToSession(buildIllegalNamespaceError(descriptiveText));
            return;
        }

        // if all is correct, go to next phase
        switch (sessionStateHolder.getState()) {

        case AUTHENTICATED:
        case ENCRYPTED:
            // do not change state!
            break;
        default:
            sessionStateHolder.setState(SessionState.STARTED);
        }

        if (responseStanza == null) {
            return;
        }
        stanzaBroker.writeToSession(responseStanza);
    }