KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > handler > IQOfflineMessagesHandler


1 /**
2  * $RCSfile: IQOfflineMessagesHandler.java,v $
3  * $Revision: 1.1 $
4  * $Date: 2005/07/26 05:05:42 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.handler;
13
14 import org.dom4j.DocumentHelper;
15 import org.dom4j.Element;
16 import org.jivesoftware.messenger.*;
17 import org.jivesoftware.messenger.auth.UnauthorizedException;
18 import org.jivesoftware.messenger.disco.*;
19 import org.jivesoftware.messenger.forms.DataForm;
20 import org.jivesoftware.messenger.forms.FormField;
21 import org.jivesoftware.messenger.forms.spi.XDataFormImpl;
22 import org.jivesoftware.messenger.forms.spi.XFormFieldImpl;
23 import org.jivesoftware.util.Log;
24 import org.xmpp.packet.IQ;
25 import org.xmpp.packet.JID;
26 import org.xmpp.packet.Message;
27
28 import java.text.SimpleDateFormat JavaDoc;
29 import java.text.ParseException JavaDoc;
30 import java.util.*;
31
32 /**
33  * Implements JEP-0013: Flexible Offline Message Retrieval. Allows users to request number of
34  * messages, request message headers, retrieve specific messages, remove specific messages,
35  * retrieve all messages and remove all messages.
36  *
37  * @author Gaston Dombiak
38  */

39 public class IQOfflineMessagesHandler extends IQHandler implements ServerFeaturesProvider,
40         DiscoInfoProvider, DiscoItemsProvider {
41
42     private static final String JavaDoc NAMESPACE = "http://jabber.org/protocol/offline";
43
44     private SimpleDateFormat JavaDoc dateFormat;
45     private IQHandlerInfo info;
46     private IQDiscoInfoHandler infoHandler;
47     private IQDiscoItemsHandler itemsHandler;
48
49     private SessionManager sessionManager;
50     private OfflineMessageStore messageStore;
51
52     public IQOfflineMessagesHandler() {
53         super("Flexible Offline Message Retrieval Handler");
54         info = new IQHandlerInfo("offline", NAMESPACE);
55         dateFormat = new SimpleDateFormat JavaDoc("yyyy-MM-DD'T'hh:mm:ss.SSS'Z'");
56         dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
57     }
58
59     public IQ handleIQ(IQ packet) throws UnauthorizedException {
60         IQ reply = IQ.createResultIQ(packet);
61         Element offlineRequest = packet.getChildElement();
62
63         if (offlineRequest.element("purge") != null) {
64             // User requested to delete all offline messages
65
messageStore.deleteMessages(packet.getFrom().getNode());
66         }
67         else if (offlineRequest.element("fetch") != null) {
68             // Mark that offline messages shouldn't be sent when the user becomes available
69
stopOfflineFlooding(packet.getFrom());
70             ClientSession session = sessionManager.getSession(packet.getFrom());
71             // User requested to receive all offline messages
72
for (OfflineMessage offlineMessage : messageStore.getMessages(
73                     packet.getFrom().getNode(), false)) {
74                 sendOfflineMessage(offlineMessage, session);
75             }
76         }
77         else {
78             for (Iterator it = offlineRequest.elementIterator("item"); it.hasNext();) {
79                 Element item = (Element) it.next();
80                 Date creationDate = null;
81                 synchronized (dateFormat) {
82                     try {
83                         creationDate = dateFormat.parse(item.attributeValue("node"));
84                     }
85                     catch (ParseException JavaDoc e) {
86                         Log.error("Error parsing date", e);
87                     }
88                 }
89                 if ("view".equals(item.attributeValue("action"))) {
90                     // User requested to receive specific message
91
OfflineMessage offlineMsg = messageStore.getMessage(packet.getFrom().getNode(),
92                             creationDate);
93                     if (offlineMsg != null) {
94                         ClientSession session = sessionManager.getSession(packet.getFrom());
95                         sendOfflineMessage(offlineMsg, session);
96                     }
97                 }
98                 else if ("remove".equals(item.attributeValue("action"))) {
99                     // User requested to delete specific message
100
messageStore.deleteMessage(packet.getFrom().getNode(), creationDate);
101                 }
102             }
103         }
104         return reply;
105     }
106
107     private void sendOfflineMessage(OfflineMessage offlineMessage, ClientSession session) {
108         Element offlineInfo = offlineMessage.addChildElement("offline", NAMESPACE);
109         synchronized (dateFormat) {
110             offlineInfo.addElement("item").addAttribute("node",
111                     dateFormat.format(offlineMessage.getCreationDate()));
112         }
113         session.process(offlineMessage);
114     }
115
116     public IQHandlerInfo getInfo() {
117         return info;
118     }
119
120     public Iterator getFeatures() {
121         ArrayList features = new ArrayList();
122         features.add(NAMESPACE);
123         return features.iterator();
124     }
125
126     public Iterator<Element> getIdentities(String JavaDoc name, String JavaDoc node, JID senderJID) {
127         ArrayList<Element> identities = new ArrayList<Element>();
128         Element identity = DocumentHelper.createElement("identity");
129         identity.addAttribute("category", "automation");
130         identity.addAttribute("type", "message-list");
131         identities.add(identity);
132         return identities.iterator();
133     }
134
135     public Iterator<String JavaDoc> getFeatures(String JavaDoc name, String JavaDoc node, JID senderJID) {
136         return Arrays.asList(NAMESPACE).iterator();
137     }
138
139     public XDataFormImpl getExtendedInfo(String JavaDoc name, String JavaDoc node, JID senderJID) {
140         // Mark that offline messages shouldn't be sent when the user becomes available
141
stopOfflineFlooding(senderJID);
142
143         XDataFormImpl dataForm = new XDataFormImpl(DataForm.TYPE_RESULT);
144
145         XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
146         field.setType(FormField.TYPE_HIDDEN);
147         field.addValue(NAMESPACE);
148         dataForm.addField(field);
149
150         field = new XFormFieldImpl("number_of_messages");
151         field.addValue(String.valueOf(messageStore.getMessages(senderJID.getNode(), false).size()));
152         dataForm.addField(field);
153
154         return dataForm;
155     }
156
157     public boolean hasInfo(String JavaDoc name, String JavaDoc node, JID senderJID) {
158         return NAMESPACE.equals(node) && senderJID.getNode() != null;
159     }
160
161     public Iterator<Element> getItems(String JavaDoc name, String JavaDoc node, JID senderJID) {
162         // Mark that offline messages shouldn't be sent when the user becomes available
163
stopOfflineFlooding(senderJID);
164         List<Element> answer = new ArrayList<Element>();
165         Element item;
166         for (OfflineMessage offlineMessage : messageStore.getMessages(senderJID.getNode(), false)) {
167             item = DocumentHelper.createElement("item");
168             item.addAttribute("jid", senderJID.toBareJID());
169             item.addAttribute("name", offlineMessage.getFrom().toString());
170             synchronized (dateFormat) {
171                 item.addAttribute("node", dateFormat.format(offlineMessage.getCreationDate()));
172             }
173
174             answer.add(item);
175         }
176
177         return answer.iterator();
178     }
179
180     public void initialize(XMPPServer server) {
181         super.initialize(server);
182         infoHandler = server.getIQDiscoInfoHandler();
183         itemsHandler = server.getIQDiscoItemsHandler();
184         messageStore = server.getOfflineMessageStore();
185         sessionManager = server.getSessionManager();
186     }
187
188     public void start() throws IllegalStateException JavaDoc {
189         super.start();
190         infoHandler.setServerNodeInfoProvider(NAMESPACE, this);
191         itemsHandler.setServerNodeInfoProvider(NAMESPACE, this);
192     }
193
194     public void stop() {
195         super.stop();
196         infoHandler.removeServerNodeInfoProvider(NAMESPACE);
197         itemsHandler.removeServerNodeInfoProvider(NAMESPACE);
198     }
199
200     private void stopOfflineFlooding(JID senderJID) {
201         ClientSession session = sessionManager.getSession(senderJID);
202         if (session != null) {
203             session.setOfflineFloodStopped(true);
204         }
205     }
206 }
207
Popular Tags