Search in sources :

Example 1 with XmppResultSet

use of com.reucon.openfire.plugin.archive.xep0059.XmppResultSet in project Openfire by igniterealtime.

the class IQListHandler method handleIQ.

public IQ handleIQ(IQ packet) throws UnauthorizedException {
    IQ reply = IQ.createResultIQ(packet);
    ListRequest listRequest = new ListRequest(packet.getChildElement());
    JID from = packet.getFrom();
    Element listElement = reply.setChildElement("list", NAMESPACE);
    Collection<Conversation> conversations = list(from, listRequest);
    XmppResultSet resultSet = listRequest.getResultSet();
    for (Conversation conversation : conversations) {
        addChatElement(listElement, conversation);
    }
    if (resultSet != null) {
        listElement.add(resultSet.createResultElement());
    }
    return reply;
}
Also used : JID(org.xmpp.packet.JID) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) Conversation(com.reucon.openfire.plugin.archive.model.Conversation) XmppResultSet(com.reucon.openfire.plugin.archive.xep0059.XmppResultSet)

Example 2 with XmppResultSet

use of com.reucon.openfire.plugin.archive.xep0059.XmppResultSet in project Openfire by igniterealtime.

the class MucMamPersistenceManager method findMessages.

@Override
public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, String owner, String with, XmppResultSet xmppResultSet) {
    JID mucRoom = new JID(owner);
    MultiUserChatManager manager = XMPPServer.getInstance().getMultiUserChatManager();
    MultiUserChatService service = manager.getMultiUserChatService(mucRoom);
    MUCRoom room = service.getChatRoom(mucRoom.getNode());
    Connection connection = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    // If logging isn't enabled, do nothing.
    if (!room.isLogEnabled())
        return null;
    List<ArchivedMessage> msgs = new LinkedList<>();
    if (startDate == null) {
        startDate = new Date(0L);
    }
    if (endDate == null) {
        endDate = new Date();
    }
    int max = xmppResultSet.getMax();
    // TODO: Suppress this, since we don't yet have requestor information for access control.
    with = null;
    try {
        connection = DbConnectionManager.getConnection();
        StringBuilder sql = new StringBuilder(LOAD_HISTORY);
        if (with != null) {
            sql.append(WHERE_SENDER);
        }
        if (xmppResultSet.getAfter() != null) {
            sql.append(WHERE_AFTER);
        }
        if (xmppResultSet.getBefore() != null) {
            sql.append(WHERE_BEFORE);
        }
        sql.append(ORDER_BY);
        pstmt = connection.prepareStatement(sql.toString());
        pstmt.setString(1, StringUtils.dateToMillis(startDate));
        pstmt.setString(2, StringUtils.dateToMillis(endDate));
        pstmt.setLong(3, room.getID());
        int pos = 3;
        if (with != null) {
            pstmt.setString(++pos, with);
        }
        if (xmppResultSet.getAfter() != null) {
            pstmt.setLong(++pos, xmppResultSet.getAfter());
        }
        if (xmppResultSet.getBefore() != null) {
            pstmt.setLong(++pos, xmppResultSet.getBefore());
        }
        rs = pstmt.executeQuery();
        while (rs.next()) {
            String senderJID = rs.getString(1);
            String nickname = rs.getString(2);
            Date sentDate = new Date(Long.parseLong(rs.getString(3).trim()));
            String subject = rs.getString(4);
            String body = rs.getString(5);
            String stanza = rs.getString(6);
            long id = rs.getLong(7);
            if (stanza == null) {
                Message message = new Message();
                message.setType(Message.Type.groupchat);
                message.setSubject(subject);
                message.setBody(body);
                // Set the sender of the message
                if (nickname != null && nickname.trim().length() > 0) {
                    JID roomJID = room.getRole().getRoleAddress();
                    // Recreate the sender address based on the nickname and room's JID
                    message.setFrom(new JID(roomJID.getNode(), roomJID.getDomain(), nickname, true));
                } else {
                    // Set the room as the sender of the message
                    message.setFrom(room.getRole().getRoleAddress());
                }
                stanza = message.toString();
            }
            ArchivedMessage archivedMessage = new ArchivedMessage(sentDate, ArchivedMessage.Direction.from, null, null);
            archivedMessage.setStanza(stanza);
            archivedMessage.setId(id);
            msgs.add(archivedMessage);
        }
    } catch (SQLException e) {
        Log.error("SQL failure during MAM-MUC: ", e);
    } finally {
        DbConnectionManager.closeConnection(rs, pstmt, connection);
    }
    // TODO - Not great, really should be done by suitable LIMIT stuff.
    // Would need to reverse ordering in some cases and then reverse results.
    boolean complete = true;
    xmppResultSet.setCount(msgs.size());
    while (msgs.size() > max) {
        msgs.remove(msgs.size() - 1);
        complete = false;
    }
    xmppResultSet.setComplete(complete);
    if (msgs.size() > 0) {
        xmppResultSet.setFirst(msgs.get(0).getId());
        if (msgs.size() > 1) {
            xmppResultSet.setLast(msgs.get(msgs.size() - 1).getId());
        }
    }
    return msgs;
}
Also used : JID(org.xmpp.packet.JID) MultiUserChatManager(org.jivesoftware.openfire.muc.MultiUserChatManager) ArchivedMessage(com.reucon.openfire.plugin.archive.model.ArchivedMessage) Message(org.xmpp.packet.Message) SQLException(java.sql.SQLException) Connection(java.sql.Connection) MultiUserChatService(org.jivesoftware.openfire.muc.MultiUserChatService) PreparedStatement(java.sql.PreparedStatement) LinkedList(java.util.LinkedList) Date(java.util.Date) MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) ArchivedMessage(com.reucon.openfire.plugin.archive.model.ArchivedMessage) ResultSet(java.sql.ResultSet) XmppResultSet(com.reucon.openfire.plugin.archive.xep0059.XmppResultSet)

Example 3 with XmppResultSet

use of com.reucon.openfire.plugin.archive.xep0059.XmppResultSet in project Openfire by igniterealtime.

the class JdbcPersistenceManager method findMessages.

@Override
public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, String ownerJid, String withJid, XmppResultSet xmppResultSet) {
    final boolean isOracleDB = isOracleDB();
    final StringBuilder querySB;
    final StringBuilder whereSB;
    final StringBuilder limitSB;
    final TreeMap<Long, ArchivedMessage> archivedMessages = new TreeMap<Long, ArchivedMessage>();
    querySB = new StringBuilder(isOracleDB ? SELECT_MESSAGE_ORACLE : SELECT_MESSAGES);
    whereSB = new StringBuilder();
    limitSB = new StringBuilder();
    // Ignore legacy messages
    appendWhere(whereSB, MESSAGE_ID, " IS NOT NULL ");
    startDate = getAuditedStartDate(startDate);
    if (startDate != null) {
        appendWhere(whereSB, MESSAGE_SENT_DATE, " >= ?");
    }
    if (endDate != null) {
        appendWhere(whereSB, MESSAGE_SENT_DATE, " <= ?");
    }
    if (ownerJid != null) {
        if (isOracleDB) {
            appendWhere(whereSB, "ofMessageArchive.conversationID in ( ", SELECT_CONVERSATIONS_BY_OWNER, " )");
        } else {
            appendWhere(whereSB, CONVERSATION_OWNER_JID, " = ?");
        }
    }
    if (withJid != null) {
        appendWhere(whereSB, "( ", MESSAGE_TO_JID, " = ? OR ", MESSAGE_FROM_JID, " = ? )");
    }
    if (whereSB.length() != 0) {
        querySB.append(" AND ").append(whereSB);
    }
    if (DbConnectionManager.getDatabaseType() == DbConnectionManager.DatabaseType.sqlserver) {
        querySB.insert(0, "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY " + MESSAGE_SENT_DATE + ") AS RowNum FROM ( ");
        querySB.append(") ofMessageArchive ) t2 WHERE RowNum");
    } else {
        querySB.append(" ORDER BY ").append(MESSAGE_SENT_DATE);
    }
    if (xmppResultSet != null) {
        Integer firstIndex = null;
        int max = xmppResultSet.getMax() != null ? xmppResultSet.getMax() : DEFAULT_MAX;
        int count = countMessages(startDate, endDate, ownerJid, withJid, whereSB.toString());
        boolean reverse = false;
        xmppResultSet.setCount(count);
        if (xmppResultSet.getIndex() != null) {
            firstIndex = xmppResultSet.getIndex();
        } else if (xmppResultSet.getAfter() != null) {
            firstIndex = countMessagesBefore(startDate, endDate, ownerJid, withJid, xmppResultSet.getAfter(), whereSB.toString());
            firstIndex += 1;
        } else if (xmppResultSet.getBefore() != null) {
            int messagesBeforeCount = countMessagesBefore(startDate, endDate, ownerJid, withJid, xmppResultSet.getBefore(), whereSB.toString());
            firstIndex = messagesBeforeCount;
            firstIndex -= max;
            // Reduce result limit to number of results before (if less than a page remaining)
            if (messagesBeforeCount < max) {
                max = messagesBeforeCount;
            }
            reverse = true;
            if (firstIndex < 0) {
                firstIndex = 0;
            }
        }
        firstIndex = firstIndex != null ? firstIndex : 0;
        if (DbConnectionManager.getDatabaseType() == DbConnectionManager.DatabaseType.sqlserver) {
            limitSB.append(" BETWEEN ").append(firstIndex + 1);
            limitSB.append(" AND ").append(firstIndex + max);
        } else if (isOracleDB()) {
            try {
                final Statement statement = DbConnectionManager.getConnection().createStatement();
                final ResultSet resultSet = statement.executeQuery("select VERSION from PRODUCT_COMPONENT_VERSION P where P.PRODUCT like 'Oracle Database%'");
                resultSet.next();
                final String versionString = resultSet.getString("VERSION");
                final String[] versionParts = versionString.split("\\.");
                final int majorVersion = Integer.parseInt(versionParts[0]);
                final int minorVersion = Integer.parseInt(versionParts[1]);
                if ((majorVersion == 12 && minorVersion >= 1) || majorVersion > 12) {
                    limitSB.append(" LIMIT ").append(max);
                    limitSB.append(" OFFSET ").append(firstIndex);
                } else {
                    querySB.insert(0, "SELECT * FROM ( ");
                    limitSB.append(" ) WHERE rownum BETWEEN ").append(firstIndex + 1).append(" AND ").append(firstIndex + max);
                }
            } catch (SQLException e) {
                Log.warn("Unable to determine oracle database version using fallback", e);
                querySB.insert(0, "SELECT * FROM ( ");
                limitSB.append(" ) WHERE rownum BETWEEN ").append(firstIndex + 1).append(" AND ").append(firstIndex + max);
            }
        } else {
            limitSB.append(" LIMIT ").append(max);
            limitSB.append(" OFFSET ").append(firstIndex);
        }
        xmppResultSet.setFirstIndex(firstIndex);
        if (isLastPage(firstIndex, count, max, reverse)) {
            xmppResultSet.setComplete(true);
        }
    }
    querySB.append(limitSB);
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        con = DbConnectionManager.getConnection();
        pstmt = con.prepareStatement(querySB.toString());
        bindMessageParameters(startDate, endDate, ownerJid, withJid, pstmt);
        rs = pstmt.executeQuery();
        Log.debug("findMessages: SELECT_MESSAGES: " + pstmt.toString());
        while (rs.next()) {
            Date time = millisToDate(rs.getLong("sentDate"));
            ArchivedMessage archivedMessage = new ArchivedMessage(time, null, null, null);
            archivedMessage.setId(rs.getLong("messageID"));
            archivedMessage.setStanza(rs.getString("stanza"));
            archivedMessages.put(archivedMessage.getId(), archivedMessage);
        }
    } catch (SQLException sqle) {
        Log.error("Error selecting conversations", sqle);
    } finally {
        DbConnectionManager.closeConnection(rs, pstmt, con);
    }
    if (xmppResultSet != null && archivedMessages.size() > 0) {
        xmppResultSet.setFirst(archivedMessages.firstKey());
        xmppResultSet.setLast(archivedMessages.lastKey());
    }
    return archivedMessages.values();
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) TreeMap(java.util.TreeMap) Date(java.util.Date) ArchivedMessage(com.reucon.openfire.plugin.archive.model.ArchivedMessage) XmppResultSet(com.reucon.openfire.plugin.archive.xep0059.XmppResultSet) ResultSet(java.sql.ResultSet)

Example 4 with XmppResultSet

use of com.reucon.openfire.plugin.archive.xep0059.XmppResultSet in project Openfire by igniterealtime.

the class JdbcPersistenceManager method findConversations.

public Collection<Conversation> findConversations(Date startDate, Date endDate, String ownerJid, String withJid, XmppResultSet xmppResultSet) {
    final TreeMap<Long, Conversation> conversations;
    final StringBuilder querySB;
    final StringBuilder whereSB;
    final StringBuilder limitSB;
    conversations = new TreeMap<Long, Conversation>();
    querySB = new StringBuilder(SELECT_CONVERSATIONS);
    whereSB = new StringBuilder();
    limitSB = new StringBuilder();
    startDate = getAuditedStartDate(startDate);
    if (startDate != null) {
        appendWhere(whereSB, CONVERSATION_START_TIME, " >= ?");
    }
    if (endDate != null) {
        appendWhere(whereSB, CONVERSATION_END_TIME, " <= ?");
    }
    if (ownerJid != null) {
        appendWhere(whereSB, CONVERSATION_OWNER_JID, " = ?");
    }
    if (withJid != null) {
        appendWhere(whereSB, CONVERSATION_WITH_JID, " = ?");
    }
    if (xmppResultSet != null) {
        Integer firstIndex = null;
        int max = xmppResultSet.getMax() != null ? xmppResultSet.getMax() : DEFAULT_MAX;
        xmppResultSet.setCount(countConversations(startDate, endDate, ownerJid, withJid, whereSB.toString()));
        if (xmppResultSet.getIndex() != null) {
            firstIndex = xmppResultSet.getIndex();
        } else if (xmppResultSet.getAfter() != null) {
            firstIndex = countConversationsBefore(startDate, endDate, ownerJid, withJid, xmppResultSet.getAfter(), whereSB.toString());
            firstIndex += 1;
        } else if (xmppResultSet.getBefore() != null) {
            firstIndex = countConversationsBefore(startDate, endDate, ownerJid, withJid, xmppResultSet.getBefore(), whereSB.toString());
            firstIndex -= max;
            if (firstIndex < 0) {
                firstIndex = 0;
            }
        }
        firstIndex = firstIndex != null ? firstIndex : 0;
        if (DbConnectionManager.getDatabaseType() == DbConnectionManager.DatabaseType.sqlserver) {
            limitSB.append(" BETWEEN ").append(firstIndex + 1);
            limitSB.append(" AND ").append(firstIndex + max);
        } else {
            limitSB.append(" LIMIT ").append(max);
            limitSB.append(" OFFSET ").append(firstIndex);
        }
        xmppResultSet.setFirstIndex(firstIndex);
    }
    if (whereSB.length() != 0) {
        querySB.append(" WHERE ").append(whereSB);
    }
    querySB.append(SELECT_CONVERSATIONS_GROUP_BY);
    if (DbConnectionManager.getDatabaseType() == DbConnectionManager.DatabaseType.sqlserver) {
        querySB.insert(0, "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY " + CONVERSATION_ID + ") AS RowNum FROM ( ");
        querySB.append(") ofConversation ) t2 WHERE RowNum");
    } else {
        querySB.append(" ORDER BY ").append(CONVERSATION_ID);
    }
    querySB.append(limitSB);
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        con = DbConnectionManager.getConnection();
        pstmt = con.prepareStatement(querySB.toString());
        bindConversationParameters(startDate, endDate, ownerJid, withJid, pstmt);
        rs = pstmt.executeQuery();
        Log.debug("findConversations: SELECT_CONVERSATIONS: " + pstmt.toString());
        while (rs.next()) {
            Conversation conv = extractConversation(rs);
            conversations.put(conv.getId(), conv);
        }
    } catch (SQLException sqle) {
        Log.error("Error selecting conversations", sqle);
    } finally {
        DbConnectionManager.closeConnection(rs, pstmt, con);
    }
    if (xmppResultSet != null && conversations.size() > 0) {
        xmppResultSet.setFirst(conversations.firstKey());
        xmppResultSet.setLast(conversations.lastKey());
    }
    return conversations.values();
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) XmppResultSet(com.reucon.openfire.plugin.archive.xep0059.XmppResultSet) ResultSet(java.sql.ResultSet) Conversation(com.reucon.openfire.plugin.archive.model.Conversation) PreparedStatement(java.sql.PreparedStatement)

Example 5 with XmppResultSet

use of com.reucon.openfire.plugin.archive.xep0059.XmppResultSet in project Openfire by igniterealtime.

the class IQRetrieveHandler method handleIQ.

public IQ handleIQ(IQ packet) throws UnauthorizedException {
    final IQ reply = IQ.createResultIQ(packet);
    final RetrieveRequest retrieveRequest = new RetrieveRequest(packet.getChildElement());
    // inclusive
    int fromIndex;
    // exclusive
    int toIndex;
    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;
}
Also used : ArchivedMessage(com.reucon.openfire.plugin.archive.model.ArchivedMessage) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) Conversation(com.reucon.openfire.plugin.archive.model.Conversation) XmppResultSet(com.reucon.openfire.plugin.archive.xep0059.XmppResultSet)

Aggregations

XmppResultSet (com.reucon.openfire.plugin.archive.xep0059.XmppResultSet)6 ArchivedMessage (com.reucon.openfire.plugin.archive.model.ArchivedMessage)4 Conversation (com.reucon.openfire.plugin.archive.model.Conversation)3 Connection (java.sql.Connection)3 PreparedStatement (java.sql.PreparedStatement)3 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3 Date (java.util.Date)2 Element (org.dom4j.Element)2 IQ (org.xmpp.packet.IQ)2 JID (org.xmpp.packet.JID)2 Statement (java.sql.Statement)1 LinkedList (java.util.LinkedList)1 TreeMap (java.util.TreeMap)1 MUCRoom (org.jivesoftware.openfire.muc.MUCRoom)1 MultiUserChatManager (org.jivesoftware.openfire.muc.MultiUserChatManager)1 MultiUserChatService (org.jivesoftware.openfire.muc.MultiUserChatService)1 Message (org.xmpp.packet.Message)1