KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > smackx > OfflineMessageManager


1 /**
2  * $RCSfile$
3  * $Revision: 2512 $
4  * $Date: 2005-07-26 01:57:36 -0300 (Tue, 26 Jul 2005) $
5  *
6  * Copyright 2003-2004 Jive Software.
7  *
8  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */

20
21 package org.jivesoftware.smackx;
22
23 import org.jivesoftware.smack.PacketCollector;
24 import org.jivesoftware.smack.SmackConfiguration;
25 import org.jivesoftware.smack.XMPPConnection;
26 import org.jivesoftware.smack.XMPPException;
27 import org.jivesoftware.smack.filter.*;
28 import org.jivesoftware.smack.packet.IQ;
29 import org.jivesoftware.smack.packet.Message;
30 import org.jivesoftware.smack.packet.Packet;
31 import org.jivesoftware.smackx.packet.DiscoverInfo;
32 import org.jivesoftware.smackx.packet.DiscoverItems;
33 import org.jivesoftware.smackx.packet.OfflineMessageInfo;
34 import org.jivesoftware.smackx.packet.OfflineMessageRequest;
35
36 import java.util.ArrayList JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.List JavaDoc;
39
40 /**
41  * The OfflineMessageManager helps manage offline messages even before the user has sent an
42  * available presence. When a user asks for his offline messages before sending an available
43  * presence then the server will not send a flood with all the offline messages when the user
44  * becomes online. The server will not send a flood with all the offline messages to the session
45  * that made the offline messages request or to any other session used by the user that becomes
46  * online.<p>
47  *
48  * Once the session that made the offline messages request has been closed and the user becomes
49  * offline in all the resources then the server will resume storing the messages offline and will
50  * send all the offline messages to the user when he becomes online. Therefore, the server will
51  * flood the user when he becomes online unless the user uses this class to manage his offline
52  * messages.
53  *
54  * @author Gaston Dombiak
55  */

56 public class OfflineMessageManager {
57
58     private final static String JavaDoc namespace = "http://jabber.org/protocol/offline";
59
60     private XMPPConnection connection;
61
62     private PacketFilter packetFilter;
63
64     public OfflineMessageManager(XMPPConnection connection) {
65         this.connection = connection;
66         packetFilter =
67                 new AndFilter(new PacketExtensionFilter("offline", namespace),
68                         new PacketTypeFilter(Message.class));
69     }
70
71     /**
72      * Returns true if the server supports Flexible Offline Message Retrieval. When the server
73      * supports Flexible Offline Message Retrieval it is possible to get the header of the offline
74      * messages, get specific messages, delete specific messages, etc.
75      *
76      * @return a boolean indicating if the server supports Flexible Offline Message Retrieval.
77      * @throws XMPPException If the user is not allowed to make this request.
78      */

79     public boolean supportsFlexibleRetrieval() throws XMPPException {
80         DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(null);
81         return info.containsFeature(namespace);
82     }
83
84     /**
85      * Returns the number of offline messages for the user of the connection.
86      *
87      * @return the number of offline messages for the user of the connection.
88      * @throws XMPPException If the user is not allowed to make this request or the server does
89      * not support offline message retrieval.
90      */

91     public int getMessageCount() throws XMPPException {
92         DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(null,
93                 namespace);
94         Form extendedInfo = Form.getFormFrom(info);
95         if (extendedInfo != null) {
96             String JavaDoc value = (String JavaDoc) extendedInfo.getField("number_of_messages").getValues().next();
97             return Integer.parseInt(value);
98         }
99         return 0;
100     }
101
102     /**
103      * Returns an iterator on <tt>OfflineMessageHeader</tt> that keep information about the
104      * offline message. The OfflineMessageHeader includes a stamp that could be used to retrieve
105      * the complete message or delete the specific message.
106      *
107      * @return an iterator on <tt>OfflineMessageHeader</tt> that keep information about the offline
108      * message.
109      * @throws XMPPException If the user is not allowed to make this request or the server does
110      * not support offline message retrieval.
111      */

112     public Iterator JavaDoc getHeaders() throws XMPPException {
113         List JavaDoc answer = new ArrayList JavaDoc();
114         DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems(
115                 null, namespace);
116         for (Iterator JavaDoc it = items.getItems(); it.hasNext();) {
117             DiscoverItems.Item item = (DiscoverItems.Item) it.next();
118             answer.add(new OfflineMessageHeader(item));
119         }
120         return answer.iterator();
121     }
122
123     /**
124      * Returns an Iterator with the offline <tt>Messages</tt> whose stamp matches the specified
125      * request. The request will include the list of stamps that uniquely identifies
126      * the offline messages to retrieve. The returned offline messages will not be deleted
127      * from the server. Use {@link #deleteMessages(java.util.List)} to delete the messages.
128      *
129      * @param nodes the list of stamps that uniquely identifies offline message.
130      * @return an Iterator with the offline <tt>Messages</tt> that were received as part of
131      * this request.
132      * @throws XMPPException If the user is not allowed to make this request or the server does
133      * not support offline message retrieval.
134      */

135     public Iterator JavaDoc getMessages(final List JavaDoc nodes) throws XMPPException {
136         List JavaDoc messages = new ArrayList JavaDoc();
137         OfflineMessageRequest request = new OfflineMessageRequest();
138         for (Iterator JavaDoc it = nodes.iterator(); it.hasNext();) {
139             OfflineMessageRequest.Item item = new OfflineMessageRequest.Item((String JavaDoc) it.next());
140             item.setAction("view");
141             request.addItem(item);
142         }
143         // Filter packets looking for an answer from the server.
144
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
145         PacketCollector response = connection.createPacketCollector(responseFilter);
146         // Filter offline messages that were requested by this request
147
PacketFilter messageFilter = new AndFilter(packetFilter, new PacketFilter() {
148             public boolean accept(Packet packet) {
149                 OfflineMessageInfo info = (OfflineMessageInfo) packet.getExtension("offline",
150                         namespace);
151                 return nodes.contains(info.getNode());
152             }
153         });
154         PacketCollector messageCollector = connection.createPacketCollector(messageFilter);
155         // Send the retrieval request to the server.
156
connection.sendPacket(request);
157         // Wait up to a certain number of seconds for a reply.
158
IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
159         // Stop queuing results
160
response.cancel();
161
162         if (answer == null) {
163             throw new XMPPException("No response from server.");
164         } else if (answer.getError() != null) {
165             throw new XMPPException(answer.getError());
166         }
167
168         // Collect the received offline messages
169
Message message = (Message) messageCollector.nextResult(
170                 SmackConfiguration.getPacketReplyTimeout());
171         while (message != null) {
172             messages.add(message);
173             message =
174                     (Message) messageCollector.nextResult(
175                             SmackConfiguration.getPacketReplyTimeout());
176         }
177         // Stop queuing offline messages
178
messageCollector.cancel();
179         return messages.iterator();
180     }
181
182     /**
183      * Returns an Iterator with all the offline <tt>Messages</tt> of the user. The returned offline
184      * messages will not be deleted from the server. Use {@link #deleteMessages(java.util.List)}
185      * to delete the messages.
186      *
187      * @return an Iterator with all the offline <tt>Messages</tt> of the user.
188      * @throws XMPPException If the user is not allowed to make this request or the server does
189      * not support offline message retrieval.
190      */

191     public Iterator JavaDoc getMessages() throws XMPPException {
192         List JavaDoc messages = new ArrayList JavaDoc();
193         OfflineMessageRequest request = new OfflineMessageRequest();
194         request.setFetch(true);
195         // Filter packets looking for an answer from the server.
196
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
197         PacketCollector response = connection.createPacketCollector(responseFilter);
198         // Filter offline messages that were requested by this request
199
PacketCollector messageCollector = connection.createPacketCollector(packetFilter);
200         // Send the retrieval request to the server.
201
connection.sendPacket(request);
202         // Wait up to a certain number of seconds for a reply.
203
IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
204         // Stop queuing results
205
response.cancel();
206
207         if (answer == null) {
208             throw new XMPPException("No response from server.");
209         } else if (answer.getError() != null) {
210             throw new XMPPException(answer.getError());
211         }
212
213         // Collect the received offline messages
214
Message message = (Message) messageCollector.nextResult(
215                 SmackConfiguration.getPacketReplyTimeout());
216         while (message != null) {
217             messages.add(message);
218             message =
219                     (Message) messageCollector.nextResult(
220                             SmackConfiguration.getPacketReplyTimeout());
221         }
222         // Stop queuing offline messages
223
messageCollector.cancel();
224         return messages.iterator();
225     }
226
227     /**
228      * Deletes the specified list of offline messages. The request will include the list of
229      * stamps that uniquely identifies the offline messages to delete.
230      *
231      * @param nodes the list of stamps that uniquely identifies offline message.
232      * @throws XMPPException If the user is not allowed to make this request or the server does
233      * not support offline message retrieval.
234      */

235     public void deleteMessages(List JavaDoc nodes) throws XMPPException {
236         OfflineMessageRequest request = new OfflineMessageRequest();
237         for (Iterator JavaDoc it = nodes.iterator(); it.hasNext();) {
238             OfflineMessageRequest.Item item = new OfflineMessageRequest.Item((String JavaDoc) it.next());
239             item.setAction("remove");
240             request.addItem(item);
241         }
242         // Filter packets looking for an answer from the server.
243
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
244         PacketCollector response = connection.createPacketCollector(responseFilter);
245         // Send the deletion request to the server.
246
connection.sendPacket(request);
247         // Wait up to a certain number of seconds for a reply.
248
IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
249         // Stop queuing results
250
response.cancel();
251
252         if (answer == null) {
253             throw new XMPPException("No response from server.");
254         } else if (answer.getError() != null) {
255             throw new XMPPException(answer.getError());
256         }
257     }
258
259     /**
260      * Deletes all offline messages of the user.
261      *
262      * @throws XMPPException If the user is not allowed to make this request or the server does
263      * not support offline message retrieval.
264      */

265     public void deleteMessages() throws XMPPException {
266         OfflineMessageRequest request = new OfflineMessageRequest();
267         request.setPurge(true);
268         // Filter packets looking for an answer from the server.
269
PacketFilter responseFilter = new PacketIDFilter(request.getPacketID());
270         PacketCollector response = connection.createPacketCollector(responseFilter);
271         // Send the deletion request to the server.
272
connection.sendPacket(request);
273         // Wait up to a certain number of seconds for a reply.
274
IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
275         // Stop queuing results
276
response.cancel();
277
278         if (answer == null) {
279             throw new XMPPException("No response from server.");
280         } else if (answer.getError() != null) {
281             throw new XMPPException(answer.getError());
282         }
283     }
284 }
285
Popular Tags