package com.reucon.openfire.plugin.archive.xep0136; import com.reucon.openfire.plugin.archive.model.ArchivedMessage; import com.reucon.openfire.plugin.archive.model.Conversation; import com.reucon.openfire.plugin.archive.util.XmppDateUtil; import com.reucon.openfire.plugin.archive.xep.AbstractIQHandler; import com.reucon.openfire.plugin.archive.xep0059.XmppResultSet; import org.dom4j.Element; import org.jivesoftware.openfire.auth.UnauthorizedException; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; import org.xmpp.packet.PacketError; import java.util.List; /** * Message Archiving Retrieve Handler. */ public class IQRetrieveHandler extends AbstractIQHandler { private static final String NAMESPACE = "urn:xmpp:archive"; public IQRetrieveHandler() { super("Message Archiving Retrieve Handler", "retrieve", NAMESPACE); } public IQ handleIQ(IQ packet) throws UnauthorizedException { final IQ reply = IQ.createResultIQ(packet); final RetrieveRequest retrieveRequest = new RetrieveRequest( packet.getChildElement()); int fromIndex; // inclusive int toIndex; // exclusive int max; final Conversation conversation = retrieve(packet.getFrom(), retrieveRequest); if (conversation == null) { return error(packet, PacketError.Condition.item_not_found); } final Element chatElement = reply.setChildElement("chat", NAMESPACE); chatElement.addAttribute("with", conversation.getWithJid()); chatElement.addAttribute("start", XmppDateUtil.formatDate(conversation.getStart())); max = conversation.getMessages().size(); fromIndex = 0; toIndex = max > 0 ? max : 0; final XmppResultSet resultSet = retrieveRequest.getResultSet(); if (resultSet != null) { if (resultSet.getMax() != null && resultSet.getMax() <= max) { max = resultSet.getMax(); toIndex = fromIndex + max; } if (resultSet.getIndex() != null) { fromIndex = resultSet.getIndex(); toIndex = fromIndex + max; } else if (resultSet.getAfter() != null) { fromIndex = resultSet.getAfter().intValue() + 1; toIndex = fromIndex + max; } else if (resultSet.getBefore() != null) { if (resultSet.getBefore()!=Long.MAX_VALUE) toIndex = resultSet.getBefore().intValue(); else toIndex = conversation.getMessages().size(); fromIndex = toIndex - max; } } fromIndex = fromIndex < 0 ? 0 : fromIndex; toIndex = toIndex > conversation.getMessages().size() ? conversation .getMessages().size() : toIndex; toIndex = toIndex < fromIndex ? fromIndex : toIndex; final List<ArchivedMessage> messages = conversation.getMessages() .subList(fromIndex, toIndex); for (int i = 0; i < messages.size(); i++) { if (i == 0) { addMessageElement(chatElement, conversation, messages.get(i), null); } else { addMessageElement(chatElement, conversation, messages.get(i), messages.get(i - 1)); } } if (resultSet != null) { if (messages.size() > 0) { resultSet.setFirst((long) fromIndex); resultSet.setFirstIndex(fromIndex); resultSet.setLast((long) toIndex - 1); } resultSet.setCount(conversation.getMessages().size()); chatElement.add(resultSet.createResultElement()); } return reply; } private Conversation retrieve(JID from, RetrieveRequest request) { return getPersistenceManager(from).getConversation(from.toBareJID(), request.getWith(), request.getStart()); } private Element addMessageElement(Element parentElement, Conversation conversation, ArchivedMessage message, ArchivedMessage previousMessage) { final Element messageElement; final long secs; if (previousMessage == null) { secs = (message.getTime().getTime() - conversation.getStart().getTime()) / 1000; } else { secs = (message.getTime().getTime() - previousMessage.getTime().getTime()) / 1000; } messageElement = parentElement.addElement(message.getDirection() .toString()); messageElement.addAttribute("secs", Long.toString(secs)); if (message.getWithJid() != null) { messageElement.addAttribute("jid", message.getWithJid().toBareJID()); } messageElement.addElement("body").setText(message.getBody()); return messageElement; } }