1 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 ; 29 import java.text.ParseException ; 30 import java.util.*; 31 32 39 public class IQOfflineMessagesHandler extends IQHandler implements ServerFeaturesProvider, 40 DiscoInfoProvider, DiscoItemsProvider { 41 42 private static final String NAMESPACE = "http://jabber.org/protocol/offline"; 43 44 private SimpleDateFormat 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 ("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 messageStore.deleteMessages(packet.getFrom().getNode()); 66 } 67 else if (offlineRequest.element("fetch") != null) { 68 stopOfflineFlooding(packet.getFrom()); 70 ClientSession session = sessionManager.getSession(packet.getFrom()); 71 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 e) { 86 Log.error("Error parsing date", e); 87 } 88 } 89 if ("view".equals(item.attributeValue("action"))) { 90 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 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 name, String 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 > getFeatures(String name, String node, JID senderJID) { 136 return Arrays.asList(NAMESPACE).iterator(); 137 } 138 139 public XDataFormImpl getExtendedInfo(String name, String node, JID senderJID) { 140 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 name, String node, JID senderJID) { 158 return NAMESPACE.equals(node) && senderJID.getNode() != null; 159 } 160 161 public Iterator<Element> getItems(String name, String node, JID senderJID) { 162 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 { 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 |