1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$ 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$ 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$ 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software. 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License. 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * http://www.apache.org/licenses/LICENSE-2.0 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS, 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smackx; 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.PacketCollector; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.SmackConfiguration; 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.Connection; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.XMPPException; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.*; 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.IQ; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Message; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Packet; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverInfo; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverItems; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.OfflineMessageInfo; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.OfflineMessageRequest; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.ArrayList; 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Iterator; 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.List; 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The OfflineMessageManager helps manage offline messages even before the user has sent an 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * available presence. When a user asks for his offline messages before sending an available 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * presence then the server will not send a flood with all the offline messages when the user 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * becomes online. The server will not send a flood with all the offline messages to the session 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * that made the offline messages request or to any other session used by the user that becomes 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * online.<p> 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Once the session that made the offline messages request has been closed and the user becomes 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * offline in all the resources then the server will resume storing the messages offline and will 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * send all the offline messages to the user when he becomes online. Therefore, the server will 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * flood the user when he becomes online unless the user uses this class to manage his offline 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * messages. 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Gaston Dombiak 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class OfflineMessageManager { 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final static String namespace = "http://jabber.org/protocol/offline"; 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Connection connection; 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private PacketFilter packetFilter; 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public OfflineMessageManager(Connection connection) { 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.connection = connection; 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetFilter = 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new AndFilter(new PacketExtensionFilter("offline", namespace), 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new PacketTypeFilter(Message.class)); 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if the server supports Flexible Offline Message Retrieval. When the server 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * supports Flexible Offline Message Retrieval it is possible to get the header of the offline 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * messages, get specific messages, delete specific messages, etc. 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a boolean indicating if the server supports Flexible Offline Message Retrieval. 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If the user is not allowed to make this request. 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean supportsFlexibleRetrieval() throws XMPPException { 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(connection.getServiceName()); 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return info.containsFeature(namespace); 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the number of offline messages for the user of the connection. 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the number of offline messages for the user of the connection. 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If the user is not allowed to make this request or the server does 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not support offline message retrieval. 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int getMessageCount() throws XMPPException { 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(null, 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen namespace); 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Form extendedInfo = Form.getFormFrom(info); 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (extendedInfo != null) { 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String value = extendedInfo.getField("number_of_messages").getValues().next(); 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Integer.parseInt(value); 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return 0; 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an iterator on <tt>OfflineMessageHeader</tt> that keep information about the 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * offline message. The OfflineMessageHeader includes a stamp that could be used to retrieve 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the complete message or delete the specific message. 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return an iterator on <tt>OfflineMessageHeader</tt> that keep information about the offline 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * message. 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If the user is not allowed to make this request or the server does 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not support offline message retrieval. 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Iterator<OfflineMessageHeader> getHeaders() throws XMPPException { 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen List<OfflineMessageHeader> answer = new ArrayList<OfflineMessageHeader>(); 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen null, namespace); 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Iterator<DiscoverItems.Item> it = items.getItems(); it.hasNext();) { 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverItems.Item item = it.next(); 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen answer.add(new OfflineMessageHeader(item)); 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return answer.iterator(); 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an Iterator with the offline <tt>Messages</tt> whose stamp matches the specified 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * request. The request will include the list of stamps that uniquely identifies 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the offline messages to retrieve. The returned offline messages will not be deleted 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * from the server. Use {@link #deleteMessages(java.util.List)} to delete the messages. 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param nodes the list of stamps that uniquely identifies offline message. 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return an Iterator with the offline <tt>Messages</tt> that were received as part of 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * this request. 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If the user is not allowed to make this request or the server does 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not support offline message retrieval. 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Iterator<Message> getMessages(final List<String> nodes) throws XMPPException { 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen List<Message> messages = new ArrayList<Message>(); 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen OfflineMessageRequest request = new OfflineMessageRequest(); 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (String node : nodes) { 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen OfflineMessageRequest.Item item = new OfflineMessageRequest.Item(node); 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen item.setAction("view"); 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen request.addItem(item); 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Filter packets looking for an answer from the server. 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketFilter responseFilter = new PacketIDFilter(request.getPacketID()); 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector response = connection.createPacketCollector(responseFilter); 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Filter offline messages that were requested by this request 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketFilter messageFilter = new AndFilter(packetFilter, new PacketFilter() { 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean accept(Packet packet) { 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen OfflineMessageInfo info = (OfflineMessageInfo) packet.getExtension("offline", 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen namespace); 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return nodes.contains(info.getNode()); 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen }); 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector messageCollector = connection.createPacketCollector(messageFilter); 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Send the retrieval request to the server. 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(request); 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to a certain number of seconds for a reply. 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout()); 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing results 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.cancel(); 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (answer == null) { 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from server."); 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (answer.getError() != null) { 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(answer.getError()); 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Collect the received offline messages 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Message message = (Message) messageCollector.nextResult( 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen SmackConfiguration.getPacketReplyTimeout()); 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen while (message != null) { 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen messages.add(message); 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen message = 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen (Message) messageCollector.nextResult( 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen SmackConfiguration.getPacketReplyTimeout()); 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing offline messages 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen messageCollector.cancel(); 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return messages.iterator(); 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an Iterator with all the offline <tt>Messages</tt> of the user. The returned offline 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * messages will not be deleted from the server. Use {@link #deleteMessages(java.util.List)} 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to delete the messages. 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return an Iterator with all the offline <tt>Messages</tt> of the user. 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If the user is not allowed to make this request or the server does 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not support offline message retrieval. 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Iterator<Message> getMessages() throws XMPPException { 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen List<Message> messages = new ArrayList<Message>(); 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen OfflineMessageRequest request = new OfflineMessageRequest(); 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen request.setFetch(true); 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Filter packets looking for an answer from the server. 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketFilter responseFilter = new PacketIDFilter(request.getPacketID()); 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector response = connection.createPacketCollector(responseFilter); 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Filter offline messages that were requested by this request 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector messageCollector = connection.createPacketCollector(packetFilter); 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Send the retrieval request to the server. 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(request); 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to a certain number of seconds for a reply. 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout()); 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing results 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.cancel(); 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (answer == null) { 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from server."); 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (answer.getError() != null) { 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(answer.getError()); 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Collect the received offline messages 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Message message = (Message) messageCollector.nextResult( 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen SmackConfiguration.getPacketReplyTimeout()); 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen while (message != null) { 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen messages.add(message); 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen message = 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen (Message) messageCollector.nextResult( 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen SmackConfiguration.getPacketReplyTimeout()); 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing offline messages 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen messageCollector.cancel(); 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return messages.iterator(); 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Deletes the specified list of offline messages. The request will include the list of 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * stamps that uniquely identifies the offline messages to delete. 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param nodes the list of stamps that uniquely identifies offline message. 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If the user is not allowed to make this request or the server does 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not support offline message retrieval. 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void deleteMessages(List<String> nodes) throws XMPPException { 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen OfflineMessageRequest request = new OfflineMessageRequest(); 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (String node : nodes) { 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen OfflineMessageRequest.Item item = new OfflineMessageRequest.Item(node); 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen item.setAction("remove"); 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen request.addItem(item); 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Filter packets looking for an answer from the server. 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketFilter responseFilter = new PacketIDFilter(request.getPacketID()); 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector response = connection.createPacketCollector(responseFilter); 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Send the deletion request to the server. 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(request); 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to a certain number of seconds for a reply. 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout()); 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing results 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.cancel(); 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (answer == null) { 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from server."); 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (answer.getError() != null) { 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(answer.getError()); 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Deletes all offline messages of the user. 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException If the user is not allowed to make this request or the server does 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not support offline message retrieval. 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void deleteMessages() throws XMPPException { 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen OfflineMessageRequest request = new OfflineMessageRequest(); 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen request.setPurge(true); 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Filter packets looking for an answer from the server. 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketFilter responseFilter = new PacketIDFilter(request.getPacketID()); 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector response = connection.createPacketCollector(responseFilter); 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Send the deletion request to the server. 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(request); 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to a certain number of seconds for a reply. 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ answer = (IQ) response.nextResult(SmackConfiguration.getPacketReplyTimeout()); 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing results 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.cancel(); 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (answer == null) { 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from server."); 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (answer.getError() != null) { 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(answer.getError()); 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 285