blob: 66f5a54ba489d089d1926301a89fa4e906d70572 [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001/**
2 * $RCSfile$
3 * $Revision$
4 * $Date$
5 *
6 * Copyright 2003-2007 Jive Software.
7 *
8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package org.jivesoftware.smack;
22
23import org.jivesoftware.smack.packet.Message;
24
25import java.util.Set;
26import java.util.Collection;
27import java.util.Collections;
28import java.util.concurrent.CopyOnWriteArraySet;
29
30/**
31 * A chat is a series of messages sent between two users. Each chat has a unique
32 * thread ID, which is used to track which messages are part of a particular
33 * conversation. Some messages are sent without a thread ID, and some clients
34 * don't send thread IDs at all. Therefore, if a message without a thread ID
35 * arrives it is routed to the most recently created Chat with the message
36 * sender.
37 *
38 * @author Matt Tucker
39 */
40public class Chat {
41
42 private ChatManager chatManager;
43 private String threadID;
44 private String participant;
45 private final Set<MessageListener> listeners = new CopyOnWriteArraySet<MessageListener>();
46
47 /**
48 * Creates a new chat with the specified user and thread ID.
49 *
50 * @param chatManager the chatManager the chat will use.
51 * @param participant the user to chat with.
52 * @param threadID the thread ID to use.
53 */
54 Chat(ChatManager chatManager, String participant, String threadID) {
55 this.chatManager = chatManager;
56 this.participant = participant;
57 this.threadID = threadID;
58 }
59
60 /**
61 * Returns the thread id associated with this chat, which corresponds to the
62 * <tt>thread</tt> field of XMPP messages. This method may return <tt>null</tt>
63 * if there is no thread ID is associated with this Chat.
64 *
65 * @return the thread ID of this chat.
66 */
67 public String getThreadID() {
68 return threadID;
69 }
70
71 /**
72 * Returns the name of the user the chat is with.
73 *
74 * @return the name of the user the chat is occuring with.
75 */
76 public String getParticipant() {
77 return participant;
78 }
79
80 /**
81 * Sends the specified text as a message to the other chat participant.
82 * This is a convenience method for:
83 *
84 * <pre>
85 * Message message = chat.createMessage();
86 * message.setBody(messageText);
87 * chat.sendMessage(message);
88 * </pre>
89 *
90 * @param text the text to send.
91 * @throws XMPPException if sending the message fails.
92 */
93 public void sendMessage(String text) throws XMPPException {
94 Message message = new Message(participant, Message.Type.chat);
95 message.setThread(threadID);
96 message.setBody(text);
97 chatManager.sendMessage(this, message);
98 }
99
100 /**
101 * Sends a message to the other chat participant. The thread ID, recipient,
102 * and message type of the message will automatically set to those of this chat.
103 *
104 * @param message the message to send.
105 * @throws XMPPException if an error occurs sending the message.
106 */
107 public void sendMessage(Message message) throws XMPPException {
108 // Force the recipient, message type, and thread ID since the user elected
109 // to send the message through this chat object.
110 message.setTo(participant);
111 message.setType(Message.Type.chat);
112 message.setThread(threadID);
113 chatManager.sendMessage(this, message);
114 }
115
116 /**
117 * Adds a packet listener that will be notified of any new messages in the
118 * chat.
119 *
120 * @param listener a packet listener.
121 */
122 public void addMessageListener(MessageListener listener) {
123 if(listener == null) {
124 return;
125 }
126 // TODO these references should be weak.
127 listeners.add(listener);
128 }
129
130 public void removeMessageListener(MessageListener listener) {
131 listeners.remove(listener);
132 }
133
134 /**
135 * Returns an unmodifiable collection of all of the listeners registered with this chat.
136 *
137 * @return an unmodifiable collection of all of the listeners registered with this chat.
138 */
139 public Collection<MessageListener> getListeners() {
140 return Collections.unmodifiableCollection(listeners);
141 }
142
143 /**
144 * Creates a {@link org.jivesoftware.smack.PacketCollector} which will accumulate the Messages
145 * for this chat. Always cancel PacketCollectors when finished with them as they will accumulate
146 * messages indefinitely.
147 *
148 * @return the PacketCollector which returns Messages for this chat.
149 */
150 public PacketCollector createCollector() {
151 return chatManager.createPacketCollector(this);
152 }
153
154 /**
155 * Delivers a message directly to this chat, which will add the message
156 * to the collector and deliver it to all listeners registered with the
157 * Chat. This is used by the Connection class to deliver messages
158 * without a thread ID.
159 *
160 * @param message the message.
161 */
162 void deliver(Message message) {
163 // Because the collector and listeners are expecting a thread ID with
164 // a specific value, set the thread ID on the message even though it
165 // probably never had one.
166 message.setThread(threadID);
167
168 for (MessageListener listener : listeners) {
169 listener.processMessage(this, message);
170 }
171 }
172
173
174 @Override
175 public boolean equals(Object obj) {
176 return obj instanceof Chat
177 && threadID.equals(((Chat)obj).getThreadID())
178 && participant.equals(((Chat)obj).getParticipant());
179 }
180}