private List available()

in server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java [157:297]


    private List<Stanza> available(PresenceStanza stanza, Entity roomJid, Entity newOccupantJid, String nick,
            ServerRuntimeContext serverRuntimeContext, StanzaBroker stanzaBroker) {

        boolean newRoom = false;
        // TODO what to use for the room name?
        Room room = conference.findRoom(roomJid);
        if (room == null) {
            room = conference.createRoom(roomJid, roomJid.getNode());
            newRoom = true;
        }

        if (room == null) {
            // room not existing or access not allowed
            return createPresenceErrorStanza(roomJid, newOccupantJid, stanza.getID(), "auth", "not-authorized");
        }

        final Occupant occupant = room.findOccupantByJID(newOccupantJid);
        if (occupant != null) {
            // occupant is already in room
            room.recordLatestPresence(newOccupantJid, stanza);
            if (nick.equals(occupant.getNick())) {
                // nick unchanged, change show and status
                logger.debug("{} has updated presence in room {}", newOccupantJid, roomJid);
                for (Occupant receiver : room.getOccupants()) {
                    sendChangeShowStatus(occupant, receiver, room, getInnerElementText(stanza, "show"),
                            getInnerElementText(stanza, "status"), serverRuntimeContext, stanzaBroker);
                }
            } else {
                logger.debug("{} has requested to change nick in room {}", newOccupantJid, roomJid);
                if (room.isInRoom(nick)) {
                    // user with this nick is already in room
                    return createPresenceErrorStanza(roomJid, newOccupantJid, stanza.getID(), "cancel", "conflict");
                }

                String oldNick = occupant.getNick();
                // update the nick
                occupant.setNick(nick);

                // send out unavailable presences to all existing occupants
                for (Occupant receiver : room.getOccupants()) {
                    sendChangeNickUnavailable(occupant, oldNick, receiver, room, serverRuntimeContext, stanzaBroker);
                }

                // send out available presences to all existing occupants
                for (Occupant receiver : room.getOccupants()) {
                    sendChangeNickAvailable(occupant, receiver, room, serverRuntimeContext, stanzaBroker);
                }

            }
            room.updateLastActivity();
        } else {
            logger.debug("{} has requested to enter room {}", newOccupantJid, roomJid);

            boolean nickConflict = room.isInRoom(nick);
            boolean nickRewritten = false;
            int counter = 1; // max conflicts, to avoid DoS attacks
            String rewrittenNick = null;
            while (nickConflict && counter < 100 && room.rewritesDuplicateNick()) {
                rewrittenNick = nick + "_" + counter;
                nickConflict = room.isInRoom(rewrittenNick);
                if (nickConflict) {
                    counter++;
                } else {
                    nick = rewrittenNick;
                    nickRewritten = true;
                }
            }

            if (nickConflict) {
                logger.debug("persistent nick confict for {} entering {}", newOccupantJid, roomJid);
                // user with this nick is already in room
                return createPresenceErrorStanza(roomJid, newOccupantJid, stanza.getID(), "cancel", "conflict");
            }

            // check password if password protected
            if (room.isRoomType(RoomType.PasswordProtected)) {
                X x = X.fromStanza(stanza);
                String password = null;
                if (x != null) {
                    password = x.getPasswordValue();
                }

                if (password == null || !password.equals(room.getPassword())) {
                    logger.debug("{} is not allowed to enter room {}", newOccupantJid, roomJid);
                    // password missing or not matching
                    return createPresenceErrorStanza(roomJid, newOccupantJid, stanza.getID(), "auth", "not-authorized");
                }
            }

            Occupant newOccupant;
            try {
                newOccupant = room.addOccupant(newOccupantJid, nick);
                room.recordLatestPresence(newOccupantJid, stanza);
            } catch (RuntimeException e) {
                final String message = e.getMessage();
                logger.debug("{} has not been added as occupant to room {}, reason: " + message, newOccupantJid,
                        roomJid);
                return createPresenceErrorStanza(roomJid, newOccupantJid, stanza.getID(), "auth", message);
            }

            if (newRoom) {
                room.getAffiliations().add(newOccupantJid, Affiliation.Owner);
                newOccupant.setRole(Role.Moderator);
            }

            // if the new occupant is a server admin, he will be for the room, too
            final ServerAdministrationService adhocCommandsService = (ServerAdministrationService) serverRuntimeContext
                    .getServerRuntimeContextService(ServerAdministrationService.SERVICE_ID);
            if (adhocCommandsService != null && adhocCommandsService.isAdmin(newOccupantJid.getBareJID())) {
                final Affiliations roomAffiliations = room.getAffiliations();
                // make new occupant an Admin, but do not downgrade from Owner
                // Admin affilitation implies Moderator role (see XEP-0045 5.1.2)
                if (roomAffiliations.getAffiliation(newOccupantJid) != Affiliation.Owner) {
                    roomAffiliations.add(newOccupantJid, Affiliation.Admin);
                    newOccupant.setRole(Role.Moderator);
                }
            }

            // relay presence of all existing room occupants to the now joined occupant
            for (Occupant existingOccupant : room.getOccupants()) {
                sendOccupantPresenceToNewOccupant(newOccupant, existingOccupant, room, serverRuntimeContext,
                        stanzaBroker);
            }

            // relay presence of the newly added occupant to all existing occupants
            for (Occupant existingOccupant : room.getOccupants()) {
                sendNewOccupantPresenceToExisting(newOccupant, existingOccupant, room, serverRuntimeContext, stanza,
                        nickRewritten, stanzaBroker);
            }

            room.updateLastActivity();

            // send discussion history to user
            boolean includeJid = room.isRoomType(RoomType.NonAnonymous);
            List<Stanza> history = room.getHistory().createStanzas(newOccupant, includeJid, History.fromStanza(stanza));
            relayStanzas(newOccupantJid, history, serverRuntimeContext, stanzaBroker);

            logger.debug("{} successfully entered room {}", newOccupantJid, roomJid);
        }
        return null;
    }