001/** 002 * 003 * Copyright 2003-2007 Jive Software. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.jivesoftware.smack.chat; 019 020import org.jivesoftware.smack.StanzaCollector; 021import org.jivesoftware.smack.SmackException.NotConnectedException; 022import org.jivesoftware.smack.packet.Message; 023import org.jivesoftware.smack.util.StringUtils; 024import org.jxmpp.jid.EntityJid; 025 026import java.util.Set; 027import java.util.Collections; 028import java.util.concurrent.CopyOnWriteArraySet; 029 030/** 031 * A chat is a series of messages sent between two users. Each chat has a unique 032 * thread ID, which is used to track which messages are part of a particular 033 * conversation. Some messages are sent without a thread ID, and some clients 034 * don't send thread IDs at all. Therefore, if a message without a thread ID 035 * arrives it is routed to the most recently created Chat with the message 036 * sender. 037 * 038 * @author Matt Tucker 039 * @deprecated use <code>org.jivesoftware.smack.chat2.Chat</code> from <code>smack-extensions</code> instead. 040 */ 041@Deprecated 042public class Chat { 043 044 private ChatManager chatManager; 045 private String threadID; 046 private EntityJid participant; 047 private final Set<ChatMessageListener> listeners = new CopyOnWriteArraySet<ChatMessageListener>(); 048 049 /** 050 * Creates a new chat with the specified user and thread ID. 051 * 052 * @param chatManager the chatManager the chat will use. 053 * @param participant the user to chat with. 054 * @param threadID the thread ID to use. 055 */ 056 Chat(ChatManager chatManager, EntityJid participant, String threadID) { 057 if (StringUtils.isEmpty(threadID)) { 058 throw new IllegalArgumentException("Thread ID must not be null"); 059 } 060 this.chatManager = chatManager; 061 this.participant = participant; 062 this.threadID = threadID; 063 } 064 065 /** 066 * Returns the thread id associated with this chat, which corresponds to the 067 * <tt>thread</tt> field of XMPP messages. This method may return <tt>null</tt> 068 * if there is no thread ID is associated with this Chat. 069 * 070 * @return the thread ID of this chat. 071 */ 072 public String getThreadID() { 073 return threadID; 074 } 075 076 /** 077 * Returns the name of the user the chat is with. 078 * 079 * @return the name of the user the chat is occuring with. 080 */ 081 public EntityJid getParticipant() { 082 return participant; 083 } 084 085 /** 086 * Sends the specified text as a message to the other chat participant. 087 * This is a convenience method for: 088 * 089 * <pre> 090 * Message message = chat.createMessage(); 091 * message.setBody(messageText); 092 * chat.sendMessage(message); 093 * </pre> 094 * 095 * @param text the text to send. 096 * @throws NotConnectedException 097 * @throws InterruptedException 098 */ 099 public void sendMessage(String text) throws NotConnectedException, InterruptedException { 100 Message message = new Message(); 101 message.setBody(text); 102 sendMessage(message); 103 } 104 105 /** 106 * Sends a message to the other chat participant. The thread ID, recipient, 107 * and message type of the message will automatically set to those of this chat. 108 * 109 * @param message the message to send. 110 * @throws NotConnectedException 111 * @throws InterruptedException 112 */ 113 public void sendMessage(Message message) throws NotConnectedException, InterruptedException { 114 // Force the recipient, message type, and thread ID since the user elected 115 // to send the message through this chat object. 116 message.setTo(participant); 117 message.setType(Message.Type.chat); 118 message.setThread(threadID); 119 chatManager.sendMessage(this, message); 120 } 121 122 /** 123 * Adds a stanza(/packet) listener that will be notified of any new messages in the 124 * chat. 125 * 126 * @param listener a stanza(/packet) listener. 127 */ 128 public void addMessageListener(ChatMessageListener listener) { 129 if(listener == null) { 130 return; 131 } 132 // TODO these references should be weak. 133 listeners.add(listener); 134 } 135 136 public void removeMessageListener(ChatMessageListener listener) { 137 listeners.remove(listener); 138 } 139 140 /** 141 * Closes the Chat and removes all references to it from the {@link ChatManager}. The chat will 142 * be unusable when this method returns, so it's recommend to drop all references to the 143 * instance right after calling {@link #close()}. 144 */ 145 public void close() { 146 chatManager.closeChat(this); 147 listeners.clear(); 148 } 149 150 /** 151 * Returns an unmodifiable set of all of the listeners registered with this chat. 152 * 153 * @return an unmodifiable set of all of the listeners registered with this chat. 154 */ 155 public Set<ChatMessageListener> getListeners() { 156 return Collections.unmodifiableSet(listeners); 157 } 158 159 /** 160 * Creates a {@link org.jivesoftware.smack.StanzaCollector} which will accumulate the Messages 161 * for this chat. Always cancel StanzaCollectors when finished with them as they will accumulate 162 * messages indefinitely. 163 * 164 * @return the StanzaCollector which returns Messages for this chat. 165 */ 166 public StanzaCollector createCollector() { 167 return chatManager.createStanzaCollector(this); 168 } 169 170 /** 171 * Delivers a message directly to this chat, which will add the message 172 * to the collector and deliver it to all listeners registered with the 173 * Chat. This is used by the XMPPConnection class to deliver messages 174 * without a thread ID. 175 * 176 * @param message the message. 177 */ 178 void deliver(Message message) { 179 // Because the collector and listeners are expecting a thread ID with 180 // a specific value, set the thread ID on the message even though it 181 // probably never had one. 182 message.setThread(threadID); 183 184 for (ChatMessageListener listener : listeners) { 185 listener.processMessage(this, message); 186 } 187 } 188 189 @Override 190 public String toString() { 191 return "Chat [(participant=" + participant + "), (thread=" + threadID + ")]"; 192 } 193 194 @Override 195 public int hashCode() { 196 int hash = 1; 197 hash = hash * 31 + threadID.hashCode(); 198 hash = hash * 31 + participant.hashCode(); 199 return hash; 200 } 201 202 @Override 203 public boolean equals(Object obj) { 204 return obj instanceof Chat 205 && threadID.equals(((Chat)obj).getThreadID()) 206 && participant.equals(((Chat)obj).getParticipant()); 207 } 208}