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