private Stanza changeAffiliation()

in server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java [201:311]


    private Stanza changeAffiliation(IQStanza stanza, ServerRuntimeContext serverRuntimeContext,
            SessionContext sessionContext, IqAdminItem item, Room room, Occupant moderator, StanzaBroker stanzaBroker) {
        // only allowed by admins and owners
        if (moderator.getAffiliation() != Affiliation.Admin && moderator.getAffiliation() != Affiliation.Owner) {
            return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL, StanzaErrorCondition.NOT_ALLOWED);
        }

        Entity target = null;

        if (item.getNick() != null) {
            target = room.findOccupantByNick(item.getNick()).getJid();
        } else {
            try {
                if (item.getJid() != null) {
                    target = item.getJid();
                } else {
                    return createBadRequestError(stanza, serverRuntimeContext, sessionContext, "Missing nick for item");
                }
            } catch (EntityFormatException e) {
                return createBadRequestError(stanza, serverRuntimeContext, sessionContext, "Invalid JID");
            }
        }

        Affiliation currentAffiliation = room.getAffiliations().getAffiliation(target);
        Affiliation newAffiliation = item.getAffiliation();

        // if the target is present in the room, we need to send presence updates
        // otherwise we should send messages
        Occupant targetOccupant = room.findOccupantByJID(target);

        // notify remaining users that user got affiliation updated
        PresenceStanzaType presenceType = null;
        Status status = null;
        Role newRole;
        Entity from;
        if (targetOccupant != null) {
            newRole = targetOccupant.getRole();
            from = roomAndNick(room, targetOccupant);
        } else {
            newRole = Role.None;
            from = room.getJID();

        }

        // only owners can revoke ownership and admin
        if ((currentAffiliation == Affiliation.Owner || currentAffiliation == Affiliation.Admin)
                && moderator.getAffiliation() != Affiliation.Owner) {
            return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL, StanzaErrorCondition.NOT_ALLOWED);
        }

        // if the occupant is getting revoke as a member, and this is a members-only
        // room, he also needs to leave the room
        if ((newAffiliation == Affiliation.None && room.isRoomType(RoomType.MembersOnly))
                || newAffiliation == Affiliation.Outcast) {
            if (newAffiliation == Affiliation.Outcast && currentAffiliation.compareTo(moderator.getAffiliation()) < 0) {
                return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
                        StanzaErrorCondition.NOT_ALLOWED);
            }

            if (targetOccupant != null) {
                room.removeOccupant(target);
            }
            presenceType = PresenceStanzaType.UNAVAILABLE;

            if (newAffiliation == Affiliation.Outcast) {
                status = new Status(StatusCode.BEEN_BANNED);
            } else {
                status = new Status(StatusCode.REMOVED_BY_AFFILIATION);
            }

            newRole = Role.None;

            MucUserItem presenceItem = new MucUserItem(newAffiliation, newRole);

            if (targetOccupant != null) {
                Stanza presenceToFormerMember = MUCStanzaBuilder.createPresenceStanza(from, target, presenceType,
                        NamespaceURIs.XEP0045_MUC_USER, presenceItem, status);

                relayStanza(target, presenceToFormerMember, stanzaBroker);
            }
        } else if (newAffiliation == Affiliation.Owner || newAffiliation == Affiliation.Admin) {
            if (moderator.getAffiliation() != Affiliation.Owner) {
                return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
                        StanzaErrorCondition.NOT_ALLOWED);
            }
        }
        room.getAffiliations().add(target, newAffiliation);

        if (targetOccupant != null) {
            MucUserItem presenceItem = new MucUserItem(newAffiliation, newRole);
            for (Occupant occupant : room.getOccupants()) {
                Stanza presenceToRemaining = MUCStanzaBuilder.createPresenceStanza(from, occupant.getJid(),
                        presenceType, NamespaceURIs.XEP0045_MUC_USER, presenceItem, status);

                relayStanza(occupant.getJid(), presenceToRemaining, stanzaBroker);
            }
        } else {
            room.getAffiliations().add(target, newAffiliation);

            MucUserItem presenceItem = new MucUserItem(target, null, newAffiliation, Role.None);
            for (Occupant occupant : room.getOccupants()) {
                StanzaBuilder builder = StanzaBuilder.createMessageStanza(room.getJID(), occupant.getJid(), null, null);
                builder.addPreparedElement(presenceItem);

                relayStanza(occupant.getJid(), builder.build(), stanzaBroker);
            }
        }

        return StanzaBuilder.createIQStanza(stanza.getTo(), stanza.getFrom(), IQStanzaType.RESULT, stanza.getID())
                .build();
    }