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