SMACK-387 Added some configuration to the ChatManager to allow for different matching modes on incoming messages with no thread id.

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/branches/smack_3_4_0@13885 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
rcollier 2014-02-01 22:22:30 +00:00
parent 782448b3ec
commit 5bbf6cf224
5 changed files with 478 additions and 232 deletions

View File

@ -170,7 +170,19 @@ public class Chat {
} }
} }
@Override
public String toString() {
return "Chat [(participant=" + participant + "), (thread=" + threadID + ")]";
}
@Override
public int hashCode() {
int hash = 1;
hash = hash * 31 + threadID.hashCode();
hash = hash * 31 + participant.hashCode();
return hash;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return obj instanceof Chat return obj instanceof Chat

View File

@ -24,6 +24,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
@ -33,39 +34,59 @@ import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.ThreadFilter; import org.jivesoftware.smack.filter.ThreadFilter;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Message.Type;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.collections.ReferenceMap; import org.jivesoftware.smack.util.collections.ReferenceMap;
/** /**
* The chat manager keeps track of references to all current chats. It will not hold any references * The chat manager keeps track of references to all current chats. It will not hold any references
* in memory on its own so it is neccesary to keep a reference to the chat object itself. To be * in memory on its own so it is necessary to keep a reference to the chat object itself. To be
* made aware of new chats, register a listener by calling {@link #addChatListener(ChatManagerListener)}. * made aware of new chats, register a listener by calling {@link #addChatListener(ChatManagerListener)}.
* *
* @author Alexander Wenckus * @author Alexander Wenckus
*/ */
public class ChatManager { public class ChatManager {
/*
/** * Sets the default behaviour for allowing 'normal' messages to be used in chats. As some clients don't set
* Returns the next unique id. Each id made up of a short alphanumeric * the message type to chat, the type normal has to be accepted to allow chats with these clients.
* prefix along with a unique numeric value.
*
* @return the next id.
*/ */
private static synchronized String nextID() { private static boolean defaultIsNormalInclude = true;
return prefix + Long.toString(id++);
/*
* Sets the default behaviour for how to match chats when there is NO thread id in the incoming message.
*/
private static MatchMode defaultMatchMode = MatchMode.BARE_JID;
/**
* Defines the different modes under which a match will be attempted with an existing chat when
* the incoming message does not have a thread id.
*/
public enum MatchMode {
/**
* Will not attempt to match, always creates a new chat.
*/
NONE,
/**
* Will match on the JID in the from field of the message.
*/
SUPPLIED_JID,
/**
* Will attempt to match on the JID in the from field, and then attempt the base JID if no match was found.
* This is the most lenient matching.
*/
BARE_JID;
} }
/** /*
* A prefix helps to make sure that ID's are unique across mutliple instances. * Determines whether incoming messages of type normal can create chats.
*/ */
private static String prefix = StringUtils.randomString(5); private boolean normalIncluded = defaultIsNormalInclude;
/** /*
* Keeps track of the current increment, which is appended to the prefix to * Determines how incoming message with no thread will be matched to existing chats.
* forum a unique ID.
*/ */
private static long id = 0; private MatchMode matchMode = defaultMatchMode;
/** /**
* Maps thread ID to chat. * Maps thread ID to chat.
*/ */
@ -101,11 +122,11 @@ public class ChatManager {
return false; return false;
} }
Message.Type messageType = ((Message) packet).getType(); Message.Type messageType = ((Message) packet).getType();
return messageType != Message.Type.groupchat && return (messageType == Type.chat) || (normalIncluded ? messageType == Type.normal : false);
messageType != Message.Type.headline;
} }
}; };
// Add a listener for all message packets so that we can deliver errant
// Add a listener for all message packets so that we can deliver
// messages to the best Chat instance available. // messages to the best Chat instance available.
connection.addPacketListener(new PacketListener() { connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) { public void processPacket(Packet packet) {
@ -116,10 +137,6 @@ public class ChatManager {
} }
else { else {
chat = getThreadChat(message.getThread()); chat = getThreadChat(message.getThread());
if (chat == null) {
// Try to locate the chat based on the sender of the message
chat = getUserChat(message.getFrom());
}
} }
if(chat == null) { if(chat == null) {
@ -130,6 +147,44 @@ public class ChatManager {
}, filter); }, filter);
} }
/**
* Determines whether incoming messages of type <i>normal</i> will be used for creating new chats or matching
* a message to existing ones.
*
* @return true if normal is allowed, false otherwise.
*/
public boolean isNormalIncluded() {
return normalIncluded;
}
/**
* Sets whether to allow incoming messages of type <i>normal</i> to be used for creating new chats or matching
* a message to an existing one.
*
* @param normalIncluded true to allow normal, false otherwise.
*/
public void setNormalIncluded(boolean normalIncluded) {
this.normalIncluded = normalIncluded;
}
/**
* Gets the current mode for matching messages with <b>NO</b> thread id to existing chats.
*
* @return The current mode.
*/
public MatchMode getMatchMode() {
return matchMode;
}
/**
* Sets the mode for matching messages with <b>NO</b> thread id to existing chats.
*
* @param matchMode The mode to set.
*/
public void setMatchMode(MatchMode matchMode) {
this.matchMode = matchMode;
}
/** /**
* Creates a new chat and returns it. * Creates a new chat and returns it.
* *
@ -138,12 +193,7 @@ public class ChatManager {
* @return the created chat. * @return the created chat.
*/ */
public Chat createChat(String userJID, MessageListener listener) { public Chat createChat(String userJID, MessageListener listener) {
String threadID; return createChat(userJID, null, listener);
do {
threadID = nextID();
} while (threadChats.get(threadID) != null);
return createChat(userJID, threadID, listener);
} }
/** /**
@ -155,7 +205,7 @@ public class ChatManager {
* @return the created chat. * @return the created chat.
*/ */
public Chat createChat(String userJID, String thread, MessageListener listener) { public Chat createChat(String userJID, String thread, MessageListener listener) {
if(thread == null) { if (thread == null) {
thread = nextID(); thread = nextID();
} }
Chat chat = threadChats.get(thread); Chat chat = threadChats.get(thread);
@ -191,20 +241,25 @@ public class ChatManager {
} }
/** /**
* Try to get a matching chat for the given user JID. Try the full * Try to get a matching chat for the given user JID, based on the {@link MatchMode}.
* JID map first, the try to match on the base JID if no match is * <li>NONE - return null
* found. * <li>SUPPLIED_JID - match the jid in the from field of the message exactly.
* <li>BARE_JID - if not match for from field, try the bare jid.
* *
* @param userJID * @param userJID jid in the from field of message.
* @return * @return Matching chat, or null if no match found.
*/ */
private Chat getUserChat(String userJID) { private Chat getUserChat(String userJID) {
Chat match = jidChats.get(userJID); if (matchMode == MatchMode.NONE) {
return null;
}
Chat match = jidChats.get(userJID);
if (match == null) { if (match == null && (matchMode == MatchMode.BARE_JID)) {
match = baseJidChats.get(StringUtils.parseBareAddress(userJID)); match = baseJidChats.get(StringUtils.parseBareAddress(userJID));
} }
return match; return match;
} }
public Chat getThreadChat(String thread) { public Chat getThreadChat(String thread) {
@ -278,4 +333,21 @@ public class ChatManager {
interceptors.put(packetInterceptor, filter); interceptors.put(packetInterceptor, filter);
} }
} }
/**
* Returns a unique id.
*
* @return the next id.
*/
private static String nextID() {
return UUID.randomUUID().toString();
}
public static void setDefaultMatchMode(MatchMode mode) {
defaultMatchMode = mode;
}
public static void setDefaultIsNormalIncluded(boolean allowNormal) {
defaultIsNormalInclude = allowNormal;
}
} }

View File

@ -80,7 +80,10 @@ public class Message extends Packet {
*/ */
public Message(String to, Type type) { public Message(String to, Type type) {
setTo(to); setTo(to);
this.type = type;
if (type != null) {
this.type = type;
}
} }
/** /**

View File

@ -452,6 +452,7 @@ public abstract class Packet {
return DEFAULT_LANGUAGE; return DEFAULT_LANGUAGE;
} }
@Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
@ -472,6 +473,7 @@ public abstract class Packet {
return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null); return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null);
} }
@Override
public int hashCode() { public int hashCode() {
int result; int result;
result = (xmlns != null ? xmlns.hashCode() : 0); result = (xmlns != null ? xmlns.hashCode() : 0);
@ -483,4 +485,9 @@ public abstract class Packet {
result = 31 * result + (error != null ? error.hashCode() : 0); result = 31 * result + (error != null ? error.hashCode() : 0);
return result; return result;
} }
@Override
public String toString() {
return toXML();
}
} }

View File

@ -22,267 +22,419 @@ package org.jivesoftware.smack;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.jivesoftware.smack.ChatManager.MatchMode;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Message.Type;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
/**
* Tests that verifies the correct behavior of the {@see Roster} implementation.
*
* @see Roster
* @see <a href="http://xmpp.org/rfcs/rfc3921.html#roster">Roster Management</a>
* @author Guenther Niess
*/
public class ChatConnectionTest { public class ChatConnectionTest {
private DummyConnection connection; private DummyConnection connection;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
// Uncomment this to enable debug output connection = getConnection();
//Connection.DEBUG_ENABLED = true;
connection = new DummyConnection();
connection.connect();
connection.login("me", "secret");
} }
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
if (connection != null) if (connection != null)
connection.disconnect(); connection.disconnect();
}
@Test
public void validateDefaultSetNormalIncluded() {
ChatManager.setDefaultIsNormalIncluded(false);
assertFalse(getConnection().getChatManager().isNormalIncluded());
ChatManager.setDefaultIsNormalIncluded(true);
assertTrue(getConnection().getChatManager().isNormalIncluded());
}
@Test
public void validateDefaultSetMatchMode() {
ChatManager.setDefaultMatchMode(MatchMode.NONE);
assertEquals(MatchMode.NONE, getConnection().getChatManager().getMatchMode());
ChatManager.setDefaultMatchMode(MatchMode.BARE_JID);
assertEquals(MatchMode.BARE_JID, getConnection().getChatManager().getMatchMode());
}
@Test
public void validateMessageTypeWithDefaults() {
DummyConnection dc = getConnection();
ChatManager cm = dc.getChatManager();
TestChatManagerListener listener = new TestChatManagerListener();
cm.addChatListener(listener);
Message incomingChat = createChatPacket("134", true);
incomingChat.setType(Type.chat);
processServerMessage(incomingChat, dc);
assertNotNull(listener.getNewChat());
dc = getConnection();
cm = dc.getChatManager();
listener = new TestChatManagerListener();
cm.addChatListener(listener);
incomingChat = createChatPacket("134", true);
incomingChat.setType(Type.normal);
processServerMessage(incomingChat, dc);
assertNotNull(listener.getNewChat());
dc = getConnection();
cm = dc.getChatManager();
listener = new TestChatManagerListener();
cm.addChatListener(listener);
incomingChat = createChatPacket("134", true);
incomingChat.setType(Type.groupchat);
processServerMessage(incomingChat, dc);
assertNull(listener.getNewChat());
dc = getConnection();
cm = dc.getChatManager();
listener = new TestChatManagerListener();
cm.addChatListener(listener);
incomingChat = createChatPacket("134", true);
incomingChat.setType(Type.headline);
processServerMessage(incomingChat, dc);
assertNull(listener.getNewChat());
}
@Test
public void validateMessageTypeWithNoNormal() {
ChatManager.setDefaultIsNormalIncluded(false);
DummyConnection dc = getConnection();
ChatManager cm = dc.getChatManager();
TestChatManagerListener listener = new TestChatManagerListener();
cm.addChatListener(listener);
Message incomingChat = createChatPacket("134", true);
incomingChat.setType(Type.chat);
processServerMessage(incomingChat, dc);
assertNotNull(listener.getNewChat());
dc = getConnection();
cm = dc.getChatManager();
listener = new TestChatManagerListener();
cm.addChatListener(listener);
incomingChat = createChatPacket("134", true);
incomingChat.setType(Type.normal);
processServerMessage(incomingChat, dc);
assertNull(listener.getNewChat());
}
// No thread behaviour
@Test
public void chatMatchedOnJIDWhenNoThreadBareMode() {
// MatchMode.BARE_JID is the default, so setting required.
DummyConnection con = getConnection();
TestMessageListener msgListener = new TestMessageListener();
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
con.getChatManager().addChatListener(listener);
Packet incomingChat = createChatPacket(null, true);
processServerMessage(incomingChat, con);
Chat newChat = listener.getNewChat();
assertNotNull(newChat);
// Should match on chat with full jid
incomingChat = createChatPacket(null, true);
processServerMessage(incomingChat, con);
assertEquals(2, msgListener.getNumMessages());
// Should match on chat with bare jid
incomingChat = createChatPacket(null, false);
processServerMessage(incomingChat, con);
assertEquals(3, msgListener.getNumMessages());
}
@Test
public void chatMatchedOnJIDWhenNoThreadJidMode() {
DummyConnection con = getConnection();
TestMessageListener msgListener = new TestMessageListener();
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
ChatManager cm = con.getChatManager();
cm.setMatchMode(MatchMode.SUPPLIED_JID);
cm.addChatListener(listener);
Packet incomingChat = createChatPacket(null, true);
processServerMessage(incomingChat, con);
Chat newChat = listener.getNewChat();
assertNotNull(newChat);
cm.removeChatListener(listener);
// Should match on chat with full jid
incomingChat = createChatPacket(null, true);
processServerMessage(incomingChat, con);
assertEquals(2, msgListener.getNumMessages());
// Should not match on chat with bare jid
TestChatManagerListener listener2 = new TestChatManagerListener();
cm.addChatListener(listener2);
incomingChat = createChatPacket(null, false);
processServerMessage(incomingChat, con);
assertEquals(2, msgListener.getNumMessages());
assertNotNull(listener2.getNewChat());
}
@Test
public void chatMatchedOnJIDWhenNoThreadNoneMode() {
DummyConnection con = getConnection();
TestMessageListener msgListener = new TestMessageListener();
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
ChatManager cm = con.getChatManager();
cm.setMatchMode(MatchMode.NONE);
cm.addChatListener(listener);
Packet incomingChat = createChatPacket(null, true);
processServerMessage(incomingChat, con);
Chat newChat = listener.getNewChat();
assertNotNull(newChat);
assertEquals(1, msgListener.getNumMessages());
cm.removeChatListener(listener);
// Should not match on chat with full jid
TestChatManagerListener listener2 = new TestChatManagerListener();
cm.addChatListener(listener2);
incomingChat = createChatPacket(null, true);
processServerMessage(incomingChat, con);
assertEquals(1, msgListener.getNumMessages());
assertNotNull(newChat);
cm.removeChatListener(listener2);
// Should not match on chat with bare jid
TestChatManagerListener listener3 = new TestChatManagerListener();
cm.addChatListener(listener3);
incomingChat = createChatPacket(null, false);
processServerMessage(incomingChat, con);
assertEquals(1, msgListener.getNumMessages());
assertNotNull(listener3.getNewChat());
} }
/** /**
* Confirm that a new chat is created when a chat message is received but * Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
* there is no thread id for a user with only a base jid. * id and the user is a full jid.
*/ */
@Test @Test
public void chatCreatedWithIncomingChatNoThreadBaseJid() public void chatFoundWhenNoThreadFullJid() {
{ TestChatManagerListener listener = new TestChatManagerListener();
TestChatManagerListener listener = new TestChatManagerListener(); connection.getChatManager().addChatListener(listener);
connection.getChatManager().addChatListener(listener); Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Packet incomingChat = createChatPacket(null, false); Packet incomingChat = createChatPacket(null, true);
processServerMessage(incomingChat); processServerMessage(incomingChat);
Chat newChat = listener.getNewChat(); Chat newChat = listener.getNewChat();
assertNotNull(newChat); assertNotNull(newChat);
assertTrue(newChat == outgoing);
} }
/** /**
* Confirm that a new chat is created when a chat message is received but * Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
* there is no thread id for a user with a full jid. * id and the user is a base jid.
*/ */
@Test @Test
public void chatCreatedWhenIncomingChatNoThreadFullJid() public void chatFoundWhenNoThreadBaseJid() {
{ TestChatManagerListener listener = new TestChatManagerListener();
TestChatManagerListener listener = new TestChatManagerListener(); connection.getChatManager().addChatListener(listener);
connection.getChatManager().addChatListener(listener); Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Packet incomingChat = createChatPacket(null, true); Packet incomingChat = createChatPacket(null, false);
processServerMessage(incomingChat); processServerMessage(incomingChat);
Chat newChat = listener.getNewChat(); Chat newChat = listener.getNewChat();
assertNotNull(newChat); assertNotNull(newChat);
assertTrue(newChat == outgoing);
} }
/** /**
* Confirm that an existing chat created with a base jid is matched to an * Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
* incoming chat message that has no thread id and the user is a full jid. * and the user is a full jid.
*/ */
@Test @Test
public void chatFoundWhenNoThreadFullJid() public void chatFoundWithSameThreadFullJid() {
{ TestChatManagerListener listener = new TestChatManagerListener();
TestChatManagerListener listener = new TestChatManagerListener(); connection.getChatManager().addChatListener(listener);
connection.getChatManager().addChatListener(listener); Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Packet incomingChat = createChatPacket(null, true); Packet incomingChat = createChatPacket(outgoing.getThreadID(), true);
processServerMessage(incomingChat); processServerMessage(incomingChat);
Chat newChat = listener.getNewChat(); Chat newChat = listener.getNewChat();
assertNotNull(newChat); assertNotNull(newChat);
assertTrue(newChat == outgoing); assertTrue(newChat == outgoing);
} }
/** /**
* Confirm that an existing chat created with a base jid is matched to an * Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
* incoming chat message that has no thread id and the user is a base jid. * and the user is a base jid.
*/ */
@Test @Test
public void chatFoundWhenNoThreadBaseJid() public void chatFoundWithSameThreadBaseJid() {
{ TestChatManagerListener listener = new TestChatManagerListener();
TestChatManagerListener listener = new TestChatManagerListener(); connection.getChatManager().addChatListener(listener);
connection.getChatManager().addChatListener(listener); Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Packet incomingChat = createChatPacket(null, false); Packet incomingChat = createChatPacket(outgoing.getThreadID(), false);
processServerMessage(incomingChat); processServerMessage(incomingChat);
Chat newChat = listener.getNewChat(); Chat newChat = listener.getNewChat();
assertNotNull(newChat); assertNotNull(newChat);
assertTrue(newChat == outgoing); assertTrue(newChat == outgoing);
} }
/** /**
* Confirm that an existing chat created with a base jid is matched to an * Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
* incoming chat message that has the same id and the user is a full jid. * different id and the same user as a base jid.
*/ */
@Test @Test
public void chatFoundWithSameThreadFullJid() public void chatNotFoundWithDiffThreadBaseJid() {
{ TestChatManagerListener listener = new TestChatManagerListener();
TestChatManagerListener listener = new TestChatManagerListener(); connection.getChatManager().addChatListener(listener);
connection.getChatManager().addChatListener(listener); Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Packet incomingChat = createChatPacket(outgoing.getThreadID(), true); Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
processServerMessage(incomingChat); processServerMessage(incomingChat);
Chat newChat = listener.getNewChat(); Chat newChat = listener.getNewChat();
assertNotNull(newChat); assertNotNull(newChat);
assertTrue(newChat == outgoing); assertFalse(newChat == outgoing);
} }
/** /**
* Confirm that an existing chat created with a base jid is matched to an * Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
* incoming chat message that has the same id and the user is a base jid. * different id and the same base jid.
*/ */
@Test @Test
public void chatFoundWithSameThreadBaseJid() public void chatNotFoundWithDiffThreadFullJid() {
{ TestChatManagerListener listener = new TestChatManagerListener();
TestChatManagerListener listener = new TestChatManagerListener(); connection.getChatManager().addChatListener(listener);
connection.getChatManager().addChatListener(listener); Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
Packet incomingChat = createChatPacket(outgoing.getThreadID(), false); Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
processServerMessage(incomingChat); processServerMessage(incomingChat);
Chat newChat = listener.getNewChat(); Chat newChat = listener.getNewChat();
assertNotNull(newChat); assertNotNull(newChat);
assertTrue(newChat == outgoing); assertFalse(newChat == outgoing);
} }
/**
* Confirm that an existing chat created with a base jid is not matched to
* an incoming chat message that has a different id and the same user as a
* base jid.
*/
@Ignore
@Test @Test
public void chatNotFoundWithDiffThreadBaseJid() public void chatNotMatchedWithTypeNormal() {
{ TestChatManagerListener listener = new TestChatManagerListener();
TestChatManagerListener listener = new TestChatManagerListener(); DummyConnection con = getConnection();
connection.getChatManager().addChatListener(listener); ChatManager cm = con.getChatManager();
Chat outgoing = connection.getChatManager().createChat("you@testserver", null); cm.setNormalIncluded(false);
cm.addChatListener(listener);
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false); Message incomingChat = createChatPacket(null, false);
processServerMessage(incomingChat); incomingChat.setType(Type.normal);
processServerMessage(incomingChat);
Chat newChat = listener.getNewChat(); assertNull(listener.getNewChat());
assertNotNull(newChat);
assertFalse(newChat == outgoing);
} }
/** private ChatManager getChatManager(boolean includeNormal, MatchMode mode) {
* Confirm that an existing chat created with a base jid is not matched to ChatManager cm = getConnection().getChatManager();
* an incoming chat message that has a different id and the same base jid. cm.setMatchMode(mode);
*/ cm.setNormalIncluded(includeNormal);
@Ignore return cm;
@Test }
public void chatNotFoundWithDiffThreadFullJid()
{ private DummyConnection getConnection() {
TestChatManagerListener listener = new TestChatManagerListener(); DummyConnection con = new DummyConnection();
connection.getChatManager().addChatListener(listener);
Chat outgoing = connection.getChatManager().createChat("you@testserver", null); try {
con.connect();
con.login("me", "secret");
} catch (XMPPException e) {
// No need for handling in a dummy connection.
}
return con;
}
private Message createChatPacket(final String threadId, final boolean isFullJid) {
Message chatMsg = new Message("me@testserver", Message.Type.chat);
chatMsg.setBody("the body message - " + System.currentTimeMillis());
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true); if (threadId != null)
processServerMessage(incomingChat); chatMsg.setThread(threadId);
return chatMsg;
Chat newChat = listener.getNewChat();
assertNotNull(newChat);
assertFalse(newChat == outgoing);
} }
private Packet createChatPacket(final String threadId, final boolean isFullJid) private void processServerMessage(Packet incomingChat) {
{ processServerMessage(incomingChat, connection);
Message chatMsg = new Message("me@testserver", Message.Type.chat); }
chatMsg.setBody("the body message");
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : "")); private void processServerMessage(Packet incomingChat, DummyConnection con) {
TestChatServer chatServer = new TestChatServer(incomingChat, con);
if (threadId != null) chatServer.start();
chatMsg.addExtension(new PacketExtension() try {
{ chatServer.join();
@Override } catch (InterruptedException e) {
public String toXML() fail();
{ }
return "<thread>" + threadId + "</thread>";
}
@Override
public String getNamespace()
{
return null;
}
@Override
public String getElementName()
{
return "thread";
}
});
return chatMsg;
} }
private void processServerMessage(Packet incomingChat) class TestChatManagerListener implements ChatManagerListener {
{ private Chat newChat;
TestChatServer chatServer = new TestChatServer(incomingChat); private MessageListener listener;
chatServer.start();
try public TestChatManagerListener(TestMessageListener msgListener) {
{ listener = msgListener;
chatServer.join(); }
} catch (InterruptedException e)
{ public TestChatManagerListener() {
fail(); }
}
@Override
public void chatCreated(Chat chat, boolean createdLocally) {
newChat = chat;
if (listener != null)
newChat.addMessageListener(listener);
}
public Chat getNewChat() {
return newChat;
}
}
private class TestChatServer extends Thread {
private Packet chatPacket;
private DummyConnection con;
TestChatServer(Packet chatMsg, DummyConnection conect) {
chatPacket = chatMsg;
con = conect;
}
@Override
public void run() {
con.processPacket(chatPacket);
}
} }
class TestChatManagerListener implements ChatManagerListener private class TestMessageListener implements MessageListener {
{ private Chat msgChat;
private Chat newChat; private int counter = 0;
@Override @Override
public void chatCreated(Chat chat, boolean createdLocally) public void processMessage(Chat chat, Message message) {
{ msgChat = chat;
newChat = chat; counter++;
} }
public Chat getNewChat() public Chat getChat() {
{ return msgChat;
return newChat; }
}
} public int getNumMessages() {
return counter;
private class TestChatServer extends Thread }
{ };
private Packet chatPacket;
TestChatServer(Packet chatMsg)
{
chatPacket = chatMsg;
}
@Override
public void run()
{
connection.processPacket(chatPacket);
}
}
} }