org.jivesoftware.smack.filter.FromMatchesFilter Java Examples

The following examples show how to use org.jivesoftware.smack.filter.FromMatchesFilter. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MultiUserChatLight.java    From Smack with Apache License 2.0 6 votes vote down vote up
MultiUserChatLight(XMPPConnection connection, EntityJid room) {
    this.connection = connection;
    this.room = room;

    fromRoomFilter = FromMatchesFilter.create(room);
    fromRoomGroupChatFilter = new AndFilter(fromRoomFilter, MessageTypeFilter.GROUPCHAT);

    messageListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) throws NotConnectedException {
            Message message = (Message) packet;
            for (MessageListener listener : messageListeners) {
                listener.processMessage(message);
            }
        }
    };

    connection.addSyncStanzaListener(messageListener, fromRoomGroupChatFilter);
}
 
Example #2
Source File: AbstractSmackIntegrationTest.java    From Smack with Apache License 2.0 6 votes vote down vote up
/**
 * Perform action and wait until conA observes a presence form conB.
 * <p>
 * This method is usually used so that 'action' performs an operation that changes one entities
 * features/nodes/capabilities, and we want to check that another connection is able to observe this change, and use
 * that new "thing" that was added to the connection.
 * </p>
 * <p>
 * Note that this method is a workaround at best and not reliable. Because it is not guaranteed that any XEP-0030
 * related manager, e.g. EntityCapsManager, already processed the presence when this method returns.
 * </p>
 * TODO: Come up with a better solution.
 *
 * @param conA the connection to observe the presence on.
 * @param conB the connection sending the presence
 * @param action the action to perform.
 * @throws Exception in case of an exception.
 */
protected void performActionAndWaitForPresence(XMPPConnection conA, XMPPConnection conB, ThrowingRunnable action)
                throws Exception {
    final SimpleResultSyncPoint presenceReceivedSyncPoint = new SimpleResultSyncPoint();
    final StanzaListener presenceListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) {
            presenceReceivedSyncPoint.signal();
        }
    };

    // Add a stanzaListener to listen for incoming presence
    conA.addAsyncStanzaListener(presenceListener, new AndFilter(
                    PresenceTypeFilter.AVAILABLE,
                    FromMatchesFilter.create(conB.getUser())
                    ));

    action.runOrThrow();

    try {
        // wait for the dummy feature to get sent via presence
        presenceReceivedSyncPoint.waitForResult(timeout);
    } finally {
        conA.removeAsyncStanzaListener(presenceListener);
    }
}
 
Example #3
Source File: CarbonManager.java    From Smack with Apache License 2.0 5 votes vote down vote up
private void addCarbonsListener(XMPPConnection connection) {
    EntityFullJid localAddress = connection.getUser();
    if (localAddress == null) {
        // We where not connected yet and thus we don't know our XMPP address at the moment, which we need to match incoming
        // carbons securely. Abort here. The ConnectionListener above will eventually setup the carbons listener.
        return;
    }

    // XEP-0280 § 11. Security Considerations "Any forwarded copies received by a Carbons-enabled client MUST be
    // from that user's bare JID; any copies that do not meet this requirement MUST be ignored." Otherwise, if
    // those copies do not get ignored, malicious users may be able to impersonate other users. That is why the
    // 'from' matcher is important here.
    connection.addSyncStanzaListener(carbonsListener, new AndFilter(CARBON_EXTENSION_FILTER,
                    FromMatchesFilter.createBare(localAddress)));
}
 
Example #4
Source File: AgentSession.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Sets the agent's current status with the workgroup. The presence mode affects how offers
 * are routed to the agent. The possible presence modes with their meanings are as follows:<ul>
 *
 * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
 * (equivalent to Presence.Mode.CHAT).
 * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
 * However, special case, or extreme urgency chats may still be offered to the agent.
 * <li>Presence.Mode.AWAY -- the agent is not available and should not
 * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
 *
 * The max chats value is the maximum number of chats the agent is willing to have routed to
 * them at once. Some servers may be configured to only accept max chat values in a certain
 * range; for example, between two and five. In that case, the maxChats value the agent sends
 * may be adjusted by the server to a value within that range.
 *
 * @param presenceMode the presence mode of the agent.
 * @param maxChats     the maximum number of chats the agent is willing to accept.
 * @param status       sets the status message of the presence update.
 * @throws XMPPErrorException if there was an XMPP error returned.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws IllegalStateException if the agent is not online with the workgroup.
 */
public void setStatus(Presence.Mode presenceMode, int maxChats, String status)
                throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    if (!online) {
        throw new IllegalStateException("Cannot set status when the agent is not online.");
    }

    if (presenceMode == null) {
        presenceMode = Presence.Mode.available;
    }
    this.presenceMode = presenceMode;
    this.maxChats = maxChats;

    PresenceBuilder presenceBuilder = connection.getStanzaFactory().buildPresenceStanza()
            .ofType(Presence.Type.available)
            .setMode(presenceMode)
            .to(workgroupJID)
            .setStatus(status)
            ;

    // Send information about max chats and current chats as a packet extension.
    StandardExtensionElement.Builder builder = StandardExtensionElement.builder(AgentStatus.ELEMENT_NAME,
            AgentStatus.NAMESPACE);
    builder.addElement("max_chats", Integer.toString(maxChats));
    presenceBuilder.addExtension(builder.build());
    presenceBuilder.addExtension(new MetaData(this.metaData));

    Presence presence = presenceBuilder.build();
    StanzaCollector collector = this.connection.createStanzaCollectorAndSend(new AndFilter(
                    new StanzaTypeFilter(Presence.class),
                    FromMatchesFilter.create(workgroupJID)), presence);

    collector.nextResultOrThrow();
}
 
Example #5
Source File: AgentSession.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Sets the agent's current status with the workgroup. The presence mode affects how offers
 * are routed to the agent. The possible presence modes with their meanings are as follows:<ul>
 *
 * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
 * (equivalent to Presence.Mode.CHAT).
 * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
 * However, special case, or extreme urgency chats may still be offered to the agent.
 * <li>Presence.Mode.AWAY -- the agent is not available and should not
 * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
 *
 * @param presenceMode the presence mode of the agent.
 * @param status       sets the status message of the presence update.
 * @throws XMPPErrorException if there was an XMPP error returned.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws IllegalStateException if the agent is not online with the workgroup.
 */
public void setStatus(Presence.Mode presenceMode, String status) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    if (!online) {
        throw new IllegalStateException("Cannot set status when the agent is not online.");
    }

    if (presenceMode == null) {
        presenceMode = Presence.Mode.available;
    }
    this.presenceMode = presenceMode;

    PresenceBuilder presenceBuilder = connection.getStanzaFactory().buildPresenceStanza()
            .ofType(Presence.Type.available)
            .setMode(presenceMode)
            .to(getWorkgroupJID());

    if (status != null) {
        presenceBuilder.setStatus(status);
    }

    Presence presence = presenceBuilder.build();
    presence.addExtension(new MetaData(this.metaData));

    StanzaCollector collector = this.connection.createStanzaCollectorAndSend(new AndFilter(new StanzaTypeFilter(Presence.class),
            FromMatchesFilter.create(workgroupJID)), presence);

    collector.nextResultOrThrow();
}
 
Example #6
Source File: Workgroup.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Returns true if the workgroup is available for receiving new requests. The workgroup will be
 * available only when agents are available for this workgroup.
 *
 * @return true if the workgroup is available for receiving new requests.
 * @throws XMPPErrorException if there was an XMPP error returned.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 */
public boolean isAvailable() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    Presence directedPresence = connection.getStanzaFactory().buildPresenceStanza()
            .ofType(Presence.Type.available)
            .to(workgroupJID)
            .build();

    StanzaFilter typeFilter = new StanzaTypeFilter(Presence.class);
    StanzaFilter fromFilter = FromMatchesFilter.create(workgroupJID);
    StanzaCollector collector = connection.createStanzaCollectorAndSend(new AndFilter(fromFilter,
            typeFilter), directedPresence);

    Presence response = collector.nextResultOrThrow();
    return Presence.Type.available == response.getType();
}
 
Example #7
Source File: MultiUserChat.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Leave the chat room.
 *
 * @return the leave presence as reflected by the MUC.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws XMPPErrorException if there was an XMPP error returned.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws MucNotJoinedException if not joined to the Multi-User Chat.
 */
public synchronized Presence leave()
                throws NotConnectedException, InterruptedException, NoResponseException, XMPPErrorException, MucNotJoinedException {
    //  Note that this method is intentionally not guarded by
    // "if  (!joined) return" because it should be always be possible to leave the room in case the instance's
    // state does not reflect the actual state.

    final EntityFullJid myRoomJid = this.myRoomJid;
    if (myRoomJid == null) {
        throw new MucNotJoinedException(this);
    }

    // We leave a room by sending a presence packet where the "to"
    // field is in the form "roomName@service/nickname"
    Presence leavePresence = connection.getStanzaFactory().buildPresenceStanza()
            .ofType(Presence.Type.unavailable)
            .to(myRoomJid)
            .build();

    StanzaFilter reflectedLeavePresenceFilter = new AndFilter(
                    StanzaTypeFilter.PRESENCE,
                    new StanzaIdFilter(leavePresence),
                    new OrFilter(
                                    new AndFilter(FromMatchesFilter.createFull(myRoomJid), PresenceTypeFilter.UNAVAILABLE, MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF),
                                    new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR)
                                )
                            );

    // Reset occupant information first so that we are assume that we left the room even if sendStanza() would
    // throw.
    userHasLeft();

    Presence reflectedLeavePresence = connection.createStanzaCollectorAndSend(reflectedLeavePresenceFilter, leavePresence).nextResultOrThrow();

    return reflectedLeavePresence;
}
 
Example #8
Source File: MultiUserChat.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Changes the occupant's nickname to a new nickname within the room. Each room occupant
 * will receive two presence packets. One of type "unavailable" for the old nickname and one
 * indicating availability for the new nickname. The unavailable presence will contain the new
 * nickname and an appropriate status code (namely 303) as extended presence information. The
 * status code 303 indicates that the occupant is changing his/her nickname.
 *
 * @param nickname the new nickname within the room.
 * @throws XMPPErrorException if the new nickname is already in use by another occupant.
 * @throws NoResponseException if there was no response from the server.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws MucNotJoinedException if not joined to the Multi-User Chat.
 */
public synchronized void changeNickname(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, MucNotJoinedException  {
    Objects.requireNonNull(nickname, "Nickname must not be null or blank.");
    // Check that we already have joined the room before attempting to change the
    // nickname.
    if (!isJoined()) {
        throw new MucNotJoinedException(this);
    }
    final EntityFullJid jid = JidCreate.entityFullFrom(room, nickname);
    // We change the nickname by sending a presence packet where the "to"
    // field is in the form "roomName@service/nickname"
    // We don't have to signal the MUC support again
    Presence joinPresence = connection.getStanzaFactory().buildPresenceStanza()
            .to(jid)
            .ofType(Presence.Type.available)
            .build();

    // Wait for a presence packet back from the server.
    StanzaFilter responseFilter =
        new AndFilter(
            FromMatchesFilter.createFull(jid),
            new StanzaTypeFilter(Presence.class));
    StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, joinPresence);
    // Wait up to a certain number of seconds for a reply. If there is a negative reply, an
    // exception will be thrown
    response.nextResultOrThrow();

    // TODO: Shouldn't this handle nickname rewriting by the MUC service?
    setNickname(nickname);
}
 
Example #9
Source File: StreamManagementTest.java    From Smack with Apache License 2.0 5 votes vote down vote up
@SmackIntegrationTest
public void testStreamManagement(XMPPTCPConnection conOne, XMPPTCPConnection conTwo) throws InterruptedException,
                SmackException, IOException, XMPPException {
    final String body1 = "Hi, what's up? " + testRunId;
    final String body2 = "Hi, what's up? I've been just instantly shutdown" + testRunId;
    final String body3 = "Hi, what's up? I've been just resumed" + testRunId;

    final StanzaCollector collector = conTwo.createStanzaCollector(new AndFilter(
                    MessageWithBodiesFilter.INSTANCE,
                    FromMatchesFilter.createFull(conOne.getUser())));

    try {
        send(body1, conOne, conTwo);
        assertMessageWithBodyReceived(body1, collector);

        conOne.instantShutdown();

        send(body2, conOne, conTwo);

        // Reconnect with xep198
        conOne.connect().login();
        assertMessageWithBodyReceived(body2, collector);

        send(body3, conOne, conTwo);
        assertMessageWithBodyReceived(body3, collector);
    }
    finally {
        collector.cancel();
    }
}
 
Example #10
Source File: EntityCapsTest.java    From Smack with Apache License 2.0 5 votes vote down vote up
@SmackIntegrationTest
public void testLocalEntityCaps() throws InterruptedException, NoResponseException, XMPPErrorException, NotConnectedException {
    final String dummyFeature = getNewDummyFeature();
    DiscoverInfo info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer());
    assertFalse(info.containsFeature(dummyFeature));

    dropWholeEntityCapsCache();

    performActionAndWaitUntilStanzaReceived(new Runnable() {
        @Override
        public void run() {
            // This should cause a new presence stanza from con1 with and updated
            // 'ver' String
            sdmTwo.addFeature(dummyFeature);
        }
    }, conOne, new AndFilter(PresenceTypeFilter.AVAILABLE, FromMatchesFilter.create(conTwo.getUser())));

    // The presence stanza should get received by con0 and the data should
    // be recorded in the map
    // Note that while both connections use the same static Entity Caps
    // cache,
    // it's assured that *not* con1 added the data to the Entity Caps cache.
    // Every time the entities features
    // and identities change only a new caps 'ver' is calculated and send
    // with the presence stanza
    // The other connection has to receive this stanza and record the
    // information in order for this test to succeed.
    info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer());
    assertNotNull(info);
    assertTrue(info.containsFeature(dummyFeature));
}
 
Example #11
Source File: ThrottleTestReader.java    From Openfire with Apache License 2.0 4 votes vote down vote up
/**
 * Starts the throttle test reader client.
 *
 * @param args application arguments.
 */
public static void main(String [] args) {
    if (args.length != 3) {
        System.out.println("Usage: java ThrottleTestReader [server] [username] [password]");
        System.exit(0);
    }
    String server = args[0];
    String username = args[1];
    String password = args[2];
    try {
        // Connect to the server, without TLS encryption.
        ConnectionConfiguration config = new ConnectionConfiguration(server);
        config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        final XMPPConnection con = new XMPPConnection(config);
        System.out.print("Connecting to " + server + "... ");
        con.connect();

        con.login(username, password, "reader");
        System.out.print("success.");
        System.out.println("");

        // Get the "real" server address.
        server = con.getServiceName();

        final String writerAddress = username + "@" + server + "/writer";
        String readerAddress = username + "@" + server + "/reader";

        System.out.println("Registered as " + readerAddress);

        // Look for the reader process.
        System.out.print("Waiting for " + writerAddress + "...");
        PacketCollector collector = con.createPacketCollector(new AndFilter(
                new FromMatchesFilter(writerAddress), new PacketTypeFilter(Time.class)));
        Time timeRequest = (Time)collector.nextResult();
        Time timeReply = new Time(Calendar.getInstance());
        timeReply.setPacketID(timeRequest.getPacketID());
        timeReply.setType(IQ.Type.RESULT);
        timeReply.setTo(timeRequest.getFrom());
        con.sendPacket(timeReply);
        System.out.println(" found writer. Now in reading mode.");

        // Track how many packets we've read.
        con.addPacketListener(new PacketListener() {

            public void processPacket(Packet packet) {
                packetCount.getAndIncrement();
            }
        }, new PacketTypeFilter(Message.class));

        while (!done) {
            Thread.sleep(5000);
            int count = packetCount.getAndSet(0);
            System.out.println("Packets per second: " + (count/5));
        }

        // Sleep while we're reading packets.
        Thread.sleep(Integer.MAX_VALUE);
    }
    catch (Exception e) {
        System.out.println("\nError: " + e.getMessage());
    }
}
 
Example #12
Source File: AgentSession.java    From Smack with Apache License 2.0 4 votes vote down vote up
/**
 * Sets whether the agent is online with the workgroup. If the user tries to go online with
 * the workgroup but is not allowed to be an agent, an XMPPError with error code 401 will
 * be thrown.
 *
 * @param online true to set the agent as online with the workgroup.
 * @throws XMPPException if an error occurs setting the online status.
 * @throws SmackException             assertEquals(SmackException.Type.NO_RESPONSE_FROM_SERVER, e.getType());
        return;
 * @throws InterruptedException if the calling thread was interrupted.
 */
public void setOnline(boolean online) throws XMPPException, SmackException, InterruptedException {
    // If the online status hasn't changed, do nothing.
    if (this.online == online) {
        return;
    }

    Presence presence;

    // If the user is going online...
    if (online) {
        presence = connection.getStanzaFactory().buildPresenceStanza()
                .ofType(Presence.Type.available)
                .to(workgroupJID)
                .build();

        presence.addExtension(new StandardExtensionElement(AgentStatus.ELEMENT_NAME,
                AgentStatus.NAMESPACE));

        StanzaCollector collector = this.connection.createStanzaCollectorAndSend(new AndFilter(
                        new StanzaTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence);

        presence = collector.nextResultOrThrow();

        // We can safely update this iv since we didn't get any error
        this.online = online;
    }
    // Otherwise the user is going offline...
    else {
        // Update this iv now since we don't care at this point of any error
        this.online = online;

        presence = connection.getStanzaFactory().buildPresenceStanza()
                .ofType(Presence.Type.unavailable)
                .to(workgroupJID)
                .build();
        presence.addExtension(new StandardExtensionElement(AgentStatus.ELEMENT_NAME,
                AgentStatus.NAMESPACE));
        connection.sendStanza(presence);
    }
}
 
Example #13
Source File: ChatManager.java    From Smack with Apache License 2.0 4 votes vote down vote up
StanzaCollector createStanzaCollector(Chat chat) {
    return connection().createStanzaCollector(new AndFilter(new ThreadFilter(chat.getThreadID()),
                    FromMatchesFilter.create(chat.getParticipant())));
}
 
Example #14
Source File: MultiUserChat.java    From Smack with Apache License 2.0 4 votes vote down vote up
/**
 * Enter a room, as described in XEP-45 7.2.
 *
 * @param conf the configuration used to enter the room.
 * @return the returned presence by the service after the client send the initial presence in order to enter the room.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws XMPPErrorException if there was an XMPP error returned.
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws NotAMucServiceException if the entity is not a MUC serivce.
 * @see <a href="http://xmpp.org/extensions/xep-0045.html#enter">XEP-45 7.2 Entering a Room</a>
 */
private Presence enter(MucEnterConfiguration conf) throws NotConnectedException, NoResponseException,
                XMPPErrorException, InterruptedException, NotAMucServiceException {
    final DomainBareJid mucService = room.asDomainBareJid();
    if (!multiUserChatManager.providesMucService(mucService)) {
        throw new NotAMucServiceException(this);
    }
    // We enter a room by sending a presence packet where the "to"
    // field is in the form "roomName@service/nickname"
    Presence joinPresence = conf.getJoinPresence(this);

    // Setup the messageListeners and presenceListeners *before* the join presence is send.
    connection.addStanzaListener(messageListener, fromRoomGroupchatFilter);
    StanzaFilter presenceFromRoomFilter = new AndFilter(fromRoomFilter,
                    StanzaTypeFilter.PRESENCE,
                    PossibleFromTypeFilter.ENTITY_FULL_JID);
    connection.addStanzaListener(presenceListener, presenceFromRoomFilter);
    // @formatter:off
    connection.addStanzaListener(subjectListener,
                    new AndFilter(fromRoomFilter,
                                  MessageWithSubjectFilter.INSTANCE,
                                  new NotFilter(MessageTypeFilter.ERROR),
                                  // According to XEP-0045 § 8.1 "A message with a <subject/> and a <body/> or a <subject/> and a <thread/> is a
                                  // legitimate message, but it SHALL NOT be interpreted as a subject change."
                                  new NotFilter(MessageWithBodiesFilter.INSTANCE),
                                  new NotFilter(MessageWithThreadFilter.INSTANCE))
                    );
    // @formatter:on
    connection.addStanzaListener(declinesListener, new AndFilter(fromRoomFilter, DECLINE_FILTER));
    connection.addStanzaSendingListener(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room),
                    StanzaTypeFilter.PRESENCE));
    messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter);

    // Wait for a presence packet back from the server.
    // @formatter:off
    StanzaFilter responseFilter = new AndFilter(StanzaTypeFilter.PRESENCE,
                    new OrFilter(
                        // We use a bare JID filter for positive responses, since the MUC service/room may rewrite the nickname.
                        new AndFilter(FromMatchesFilter.createBare(getRoom()), MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF),
                        // In case there is an error reply, we match on an error presence with the same stanza id and from the full
                        // JID we send the join presence to.
                        new AndFilter(FromMatchesFilter.createFull(joinPresence.getTo()), new StanzaIdFilter(joinPresence), PresenceTypeFilter.ERROR)
                    )
                );
    // @formatter:on
    StanzaCollector presenceStanzaCollector = null;
    Presence presence;
    try {
        // This stanza collector will collect the final self presence from the MUC, which also signals that we have successful entered the MUC.
        StanzaCollector selfPresenceCollector = connection.createStanzaCollectorAndSend(responseFilter, joinPresence);
        StanzaCollector.Configuration presenceStanzaCollectorConfguration = StanzaCollector.newConfiguration().setCollectorToReset(
                        selfPresenceCollector).setStanzaFilter(presenceFromRoomFilter);
        // This stanza collector is used to reset the timeout of the selfPresenceCollector.
        presenceStanzaCollector = connection.createStanzaCollector(presenceStanzaCollectorConfguration);
        presence = selfPresenceCollector.nextResultOrThrow(conf.getTimeout());
    }
    catch (NotConnectedException | InterruptedException | NoResponseException | XMPPErrorException e) {
        // Ensure that all callbacks are removed if there is an exception
        removeConnectionCallbacks();
        throw e;
    }
    finally {
        if (presenceStanzaCollector != null) {
            presenceStanzaCollector.cancel();
        }
    }

    // This presence must be send from a full JID. We use the resourcepart of this JID as nick, since the room may
    // performed roomnick rewriting
    Resourcepart receivedNickname = presence.getFrom().getResourceOrThrow();
    setNickname(receivedNickname);

    // Update the list of joined rooms
    multiUserChatManager.addJoinedRoom(room);
    return presence;
}