View Javadoc

1   /*
2    * $Id: XmppMultiUserChatConversation.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.xmpp;
12  
13  import org.mule.api.endpoint.ImmutableEndpoint;
14  import org.mule.transport.ConnectException;
15  import org.mule.util.UUID;
16  
17  import org.jivesoftware.smack.PacketCollector;
18  import org.jivesoftware.smack.SmackConfiguration;
19  import org.jivesoftware.smack.XMPPException;
20  import org.jivesoftware.smack.packet.Message;
21  import org.jivesoftware.smack.packet.XMPPError;
22  import org.jivesoftware.smackx.muc.DiscussionHistory;
23  import org.jivesoftware.smackx.muc.MultiUserChat;
24  
25  public class XmppMultiUserChatConversation extends AbstractXmppConversation
26  {
27      private MultiUserChat chat;
28      private String nickname;
29      
30      public XmppMultiUserChatConversation(ImmutableEndpoint endpoint)
31      {
32          super(endpoint);
33          
34          Object nickValue = endpoint.getProperty(XmppConnector.XMPP_NICKNAME);
35          if (nickValue != null)
36          {
37              nickname = nickValue.toString();
38          }
39          else
40          {
41              nickname = UUID.getUUID().toString();
42          }
43      }
44  
45      @Override
46      protected void doConnect() throws ConnectException
47      {
48          chat = new MultiUserChat(connection, recipient);
49          joinChat();
50      }
51  
52      protected void joinChat() throws ConnectException
53      {
54          try
55          {
56              tryToJoinChat();
57          }
58          catch (XMPPException e)
59          {
60              if (roomDoesNotExist(e))
61              {
62                  createRoom();
63              }
64              else
65              {
66                  throw new ConnectException(e, this);
67              }
68          }
69      }
70      
71      protected void tryToJoinChat() throws XMPPException
72      {
73          DiscussionHistory history = new DiscussionHistory();
74          history.setMaxStanzas(0);
75          
76          // use the same default value that the smack API uses internally
77          long joinTimeout = SmackConfiguration.getPacketReplyTimeout();
78          
79          chat.join(nickname, null, history, joinTimeout);
80          if (logger.isDebugEnabled())
81          {
82              logger.debug("joined groupchat '" + recipient + "'");
83          }
84      }
85      
86      protected boolean roomDoesNotExist(XMPPException exception)
87      {
88          XMPPError error = exception.getXMPPError();
89          if ((error.getCode() == 404) &&
90              error.getCondition().equals(XMPPError.Condition.recipient_unavailable.toString()))
91          {
92              return true;
93          }
94          return false;
95      }
96      
97      protected void createRoom() throws ConnectException
98      {
99          try
100         {
101             chat.create(nickname);
102             if (logger.isDebugEnabled())
103             {
104                 logger.debug("created and joined groupchat '" + recipient + "'");
105             }
106         }
107         catch (XMPPException e)
108         {
109             throw new ConnectException(e, this);
110         }
111     }
112 
113     @Override
114     protected void doDisconnect()
115     {
116         chat.leave();
117     }
118     
119     /**
120      * This implementation returns <code>null</code> as we override {@link #receive()} and
121      * {@link #receive(long)}.
122      */
123     @Override
124     protected PacketCollector createPacketCollector()
125     {
126         return null;
127     }
128 
129     public void dispatch(Message message) throws XMPPException
130     {
131         message.setType(Message.Type.groupchat);
132         message.setTo(recipient);
133         
134         chat.sendMessage(message);
135     }
136 
137     @Override
138     public Message receive()
139     {
140         return chat.nextMessage();
141     }
142 
143     @Override
144     public Message receive(long timeout)
145     {
146         return chat.nextMessage(timeout);
147     }
148 }