Chat.java

  1. /**
  2.  *
  3.  * Copyright 2003-2007 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.jivesoftware.smack.chat;

  18. import java.util.Collections;
  19. import java.util.Set;
  20. import java.util.concurrent.CopyOnWriteArraySet;

  21. import org.jivesoftware.smack.SmackException.NotConnectedException;
  22. import org.jivesoftware.smack.StanzaCollector;
  23. import org.jivesoftware.smack.packet.Message;
  24. import org.jivesoftware.smack.packet.MessageBuilder;
  25. import org.jivesoftware.smack.packet.StanzaBuilder;
  26. import org.jivesoftware.smack.util.StringUtils;

  27. import org.jxmpp.jid.EntityJid;

  28. /**
  29.  * A chat is a series of messages sent between two users. Each chat has a unique
  30.  * thread ID, which is used to track which messages are part of a particular
  31.  * conversation. Some messages are sent without a thread ID, and some clients
  32.  * don't send thread IDs at all. Therefore, if a message without a thread ID
  33.  * arrives it is routed to the most recently created Chat with the message
  34.  * sender.
  35.  *
  36.  * @author Matt Tucker
  37.  * @deprecated use <code>org.jivesoftware.smack.chat2.Chat</code> from <code>smack-extensions</code> instead.
  38.  */
  39. @Deprecated
  40. public class Chat {

  41.     private final ChatManager chatManager;
  42.     private final String threadID;
  43.     private final EntityJid participant;
  44.     private final Set<ChatMessageListener> listeners = new CopyOnWriteArraySet<>();

  45.     /**
  46.      * Creates a new chat with the specified user and thread ID.
  47.      *
  48.      * @param chatManager the chatManager the chat will use.
  49.      * @param participant the user to chat with.
  50.      * @param threadID the thread ID to use.
  51.      */
  52.     Chat(ChatManager chatManager, EntityJid participant, String threadID) {
  53.         if (StringUtils.isEmpty(threadID)) {
  54.             throw new IllegalArgumentException("Thread ID must not be null");
  55.         }
  56.         this.chatManager = chatManager;
  57.         this.participant = participant;
  58.         this.threadID = threadID;
  59.     }

  60.     /**
  61.      * Returns the thread id associated with this chat, which corresponds to the
  62.      * <code>thread</code> field of XMPP messages. This method may return <code>null</code>
  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.      * Returns the name of the user the chat is with.
  72.      *
  73.      * @return the name of the user the chat is occurring with.
  74.      */
  75.     public EntityJid getParticipant() {
  76.         return participant;
  77.     }

  78.     /**
  79.      * Sends the specified text as a message to the other chat participant.
  80.      * This is a convenience method for:
  81.      *
  82.      * <pre>
  83.      *     Message message = chat.createMessage();
  84.      *     message.setBody(messageText);
  85.      *     chat.sendMessage(message);
  86.      * </pre>
  87.      *
  88.      * @param text the text to send.
  89.      * @throws NotConnectedException if the XMPP connection is not connected.
  90.      * @throws InterruptedException if the calling thread was interrupted.
  91.      */
  92.     public void sendMessage(String text) throws NotConnectedException, InterruptedException {
  93.         MessageBuilder message = StanzaBuilder.buildMessage()
  94.                 .setBody(text);
  95.         sendMessage(message);
  96.     }

  97.     /**
  98.      * Sends a message to the other chat participant. The thread ID, recipient,
  99.      * and message type of the message will automatically set to those of this chat.
  100.      *
  101.      * @param message the message to send.
  102.      * @throws NotConnectedException if the XMPP connection is not connected.
  103.      * @throws InterruptedException if the calling thread was interrupted.
  104.      */
  105.     public void sendMessage(MessageBuilder message) throws NotConnectedException, InterruptedException {
  106.         // Force the recipient, message type, and thread ID since the user elected
  107.         // to send the message through this chat object.
  108.         message.to(participant);
  109.         message.ofType(Message.Type.chat);
  110.         message.setThread(threadID);
  111.         chatManager.sendMessage(this, message.build());
  112.     }

  113.     /**
  114.      * Sends a message to the other chat participant. The thread ID, recipient,
  115.      * and message type of the message will automatically set to those of this chat.
  116.      *
  117.      * @param message the message to send.
  118.      * @throws NotConnectedException if the XMPP connection is not connected.
  119.      * @throws InterruptedException if the calling thread was interrupted.
  120.      */
  121.     public void sendMessage(Message message) throws NotConnectedException, InterruptedException {
  122.         // Force the recipient, message type, and thread ID since the user elected
  123.         // to send the message through this chat object.
  124.         Message chatMessage = message.asBuilder()
  125.                         .to(participant)
  126.                         .ofType(Message.Type.chat)
  127.                         .setThread(threadID)
  128.                         .build();
  129.         chatManager.sendMessage(this, chatMessage);
  130.     }

  131.     /**
  132.      * Adds a stanza listener that will be notified of any new messages in the
  133.      * chat.
  134.      *
  135.      * @param listener a stanza listener.
  136.      */
  137.     public void addMessageListener(ChatMessageListener listener) {
  138.         if (listener == null) {
  139.             return;
  140.         }
  141.         // TODO these references should be weak.
  142.         listeners.add(listener);
  143.     }

  144.     public void removeMessageListener(ChatMessageListener listener) {
  145.         listeners.remove(listener);
  146.     }

  147.     /**
  148.      * Closes the Chat and removes all references to it from the {@link ChatManager}. The chat will
  149.      * be unusable when this method returns, so it's recommend to drop all references to the
  150.      * instance right after calling {@link #close()}.
  151.      */
  152.     public void close() {
  153.         chatManager.closeChat(this);
  154.         listeners.clear();
  155.     }

  156.     /**
  157.      * Returns an unmodifiable set of all of the listeners registered with this chat.
  158.      *
  159.      * @return an unmodifiable set of all of the listeners registered with this chat.
  160.      */
  161.     public Set<ChatMessageListener> getListeners() {
  162.         return Collections.unmodifiableSet(listeners);
  163.     }

  164.     /**
  165.      * Creates a {@link org.jivesoftware.smack.StanzaCollector} which will accumulate the Messages
  166.      * for this chat. Always cancel StanzaCollectors when finished with them as they will accumulate
  167.      * messages indefinitely.
  168.      *
  169.      * @return the StanzaCollector which returns Messages for this chat.
  170.      */
  171.     public StanzaCollector createCollector() {
  172.         return chatManager.createStanzaCollector(this);
  173.     }

  174.     /**
  175.      * Delivers a message directly to this chat, which will add the message
  176.      * to the collector and deliver it to all listeners registered with the
  177.      * Chat. This is used by the XMPPConnection class to deliver messages
  178.      * without a thread ID.
  179.      *
  180.      * @param message the message.
  181.      */
  182.     void deliver(Message message) {
  183.         // Because the collector and listeners are expecting a thread ID with
  184.         // a specific value, set the thread ID on the message even though it
  185.         // probably never had one.
  186.         Message chatMessage = message.asBuilder().setThread(threadID).build();

  187.         for (ChatMessageListener listener : listeners) {
  188.             listener.processMessage(this, chatMessage);
  189.         }
  190.     }

  191.     @Override
  192.     public String toString() {
  193.         return "Chat [(participant=" + participant + "), (thread=" + threadID + ")]";
  194.     }

  195.     @Override
  196.     public int hashCode() {
  197.         int hash = 1;
  198.         hash = hash * 31 + threadID.hashCode();
  199.         hash = hash * 31 + participant.hashCode();
  200.         return hash;
  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. }