View Javadoc

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