View Javadoc

1   /*
2    * $Id: JabberClient.java 21939 2011-05-18 13:32:09Z aperepel $
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.util.UUID;
14  
15  import java.util.ArrayList;
16  import java.util.HashMap;
17  import java.util.List;
18  import java.util.Map;
19  import java.util.concurrent.CountDownLatch;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.jivesoftware.smack.Chat;
24  import org.jivesoftware.smack.ConnectionConfiguration;
25  import org.jivesoftware.smack.MessageListener;
26  import org.jivesoftware.smack.PacketCollector;
27  import org.jivesoftware.smack.PacketListener;
28  import org.jivesoftware.smack.XMPPConnection;
29  import org.jivesoftware.smack.XMPPException;
30  import org.jivesoftware.smack.filter.MessageTypeFilter;
31  import org.jivesoftware.smack.filter.OrFilter;
32  import org.jivesoftware.smack.filter.PacketFilter;
33  import org.jivesoftware.smack.packet.Message;
34  import org.jivesoftware.smack.packet.Packet;
35  import org.jivesoftware.smackx.muc.MultiUserChat;
36  
37  public class JabberClient implements PacketListener, MessageListener
38  {
39      private static Log logger = LogFactory.getLog(JabberClient.class);
40      
41      private String host;
42      private String user;
43      private String password;
44      private boolean synchronous = true;
45      private String replyPayload = "Reply";
46      private boolean autoreply = false;
47  
48      private XMPPConnection connection;
49      private Map<String, Chat> chats;
50      private MultiUserChat groupchat = null;
51      private List<Message> replies;
52      private PacketCollector packetCollector = null;
53      private CountDownLatch messageLatch = null;
54  
55      public JabberClient(String host, String user, String password) throws Exception
56      {
57          super();
58          this.host = host;
59          
60          int index = user.indexOf("@");
61          if (index > -1)
62          {
63              this.user = user.substring(0, index);
64          }
65          else
66          {
67              this.user = user;
68          }
69          
70          this.password = password;        
71  
72          replies = new ArrayList<Message>();
73          chats = new HashMap<String, Chat>();
74      }
75  
76      public void connect(CountDownLatch latch) throws Exception
77      {
78          ConnectionConfiguration connectionConfig = new ConnectionConfiguration(host);
79          // no roster required
80          connectionConfig.setRosterLoadedAtLogin(false);
81          
82          connection = new XMPPConnection(connectionConfig);
83          connection.connect();
84          if (logger.isDebugEnabled())
85          {
86              logger.debug("connected to " + host);
87          }
88          
89          connection.login(user, password);
90          if (logger.isDebugEnabled())
91          {
92              logger.debug("logged into " + host + " as " + user);
93          }
94  
95          registerListener();
96          
97          // notify the caller that we're finished connecting
98          latch.countDown();
99      }
100 
101     private void registerListener()
102     {
103         PacketFilter normalTypeFilter = new MessageTypeFilter(Message.Type.normal);
104         PacketFilter chatTypeFilter = new MessageTypeFilter(Message.Type.chat);
105         PacketFilter mucTypeFilter = new MessageTypeFilter(Message.Type.groupchat);
106         PacketFilter filter = new OrFilter(normalTypeFilter, chatTypeFilter);
107         filter = new OrFilter(filter, mucTypeFilter);
108 
109         if (synchronous)
110         {
111             packetCollector = connection.createPacketCollector(filter);
112         }
113         else
114         {
115             connection.addPacketListener(this, filter);
116         }
117     }
118 
119     public void disconnect()
120     {
121         connection.removePacketListener(this);
122         
123         if (packetCollector != null)
124         {
125             packetCollector.cancel();
126         }
127         if (groupchat != null)
128         {
129             groupchat.leave();
130         }
131         
132         chats = null;
133         connection.disconnect();
134     }
135 
136     //
137     // Jabber listeners
138     //
139     public void processPacket(Packet packet)
140     {
141         if (logger.isDebugEnabled())
142         {
143             logger.debug("received " + packet);
144         }
145         
146         // our filters make sure that we ever only see Message instances
147         replies.add((Message) packet);
148         
149         countDownMessageLatch();        
150         sendAutoreply(packet);
151     }
152 
153     public void processMessage(Chat chat, Message message)
154     {
155         if (logger.isDebugEnabled())
156         {
157             logger.debug("received from chat '" + chat.getThreadID() + ": " + message);
158         }
159         
160         replies.add(message);
161         countDownMessageLatch();
162     }
163 
164     private void countDownMessageLatch()
165     {
166         if (messageLatch != null)
167         {
168             messageLatch.countDown();
169         }
170     }
171 
172     private void sendAutoreply(Packet packet)
173     {
174         if (autoreply)
175         {
176             Message incomingMessage = (Message) packet;
177             
178             Message message = new Message();
179             message.setType(incomingMessage.getType());
180             message.setTo(incomingMessage.getFrom());
181             message.setBody(replyPayload);
182             
183             connection.sendPacket(message);
184             
185             if (logger.isDebugEnabled())
186             {
187                 logger.debug("sent autoreply message with payload: \"" + replyPayload + "\"");
188             }
189         }
190     }
191 
192     public void sendMessage(String recipient, String payload)
193     {
194         if (logger.isDebugEnabled())
195         {
196             logger.debug("Will send message to \"" + recipient + "\" with payload \"" + payload + "\"");
197         }
198         
199         Message message = buildMessage(Message.Type.normal, recipient, payload);
200         connection.sendPacket(message);
201     }
202 
203     public void sendChatMessage(String recipient, String payload) throws XMPPException
204     {
205         if (logger.isDebugEnabled())
206         {
207             logger.debug("Will send chat message to \"" + recipient + "\" with payload \"" + payload + "\"");
208         }
209 
210         Chat chat = chatWith(recipient);
211         Message message = buildMessage(Message.Type.chat, recipient, payload);
212         chat.sendMessage(message);
213     }
214     
215     private Chat chatWith(String recipient)
216     {
217         Chat chat = chats.get(recipient);
218         if (chat == null)
219         {
220             chat = connection.getChatManager().createChat(recipient, this);
221             chats.put(recipient, chat);
222         }
223         return chat;
224     }
225     
226     private Message buildMessage(Message.Type type, String recipient, String payload)
227     {
228         Message message = new Message();
229         message.setType(type);
230         
231         String from = user + "@" + host;
232         message.setFrom(from);
233         
234         message.setTo(recipient);
235         message.setBody(payload);
236 
237         return message;
238     }
239     
240     public List<Message> getReceivedMessages()
241     {
242         return replies;
243     }
244     
245     public Packet receive(long timeout)
246     {
247         return packetCollector.nextResult(timeout);
248     }
249 
250     public void joinGroupchat(String chatroom) throws XMPPException
251     {
252         groupchat = new MultiUserChat(connection, chatroom);
253         groupchat.join(UUID.getUUID().toString());
254     }
255 
256     public void sendGroupchatMessage(String text) throws XMPPException
257     {
258         groupchat.sendMessage(text);
259     }
260 
261     //
262     // setters for config parameters
263     // 
264     public void setReplyPayload(String reply)
265     {
266         replyPayload = reply;
267     }
268 
269     public void setAutoReply(boolean flag)
270     {
271         autoreply = flag;
272         // autoreply only works in an async mode
273         synchronous = false;
274     }
275     
276     public void setSynchronous(boolean flag)
277     {
278         synchronous = flag;
279     }
280 
281     public void setMessageLatch(CountDownLatch latch)
282     {
283         messageLatch = latch;
284     }
285 }