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 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
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
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
138
139 public void processPacket(Packet packet)
140 {
141 if (logger.isDebugEnabled())
142 {
143 logger.debug("received " + packet);
144 }
145
146
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
263
264 public void setReplyPayload(String reply)
265 {
266 replyPayload = reply;
267 }
268
269 public void setAutoReply(boolean flag)
270 {
271 autoreply = flag;
272
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 }