MUCRoomHistory.java 7.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
/**
 * $RCSfile: MUCRoomHistory.java,v $
 * $Revision: 3157 $
 * $Date: 2005-12-04 22:54:55 -0300 (Sun, 04 Dec 2005) $
 *
 * Copyright (C) 2004 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.openfire.muc;

import org.dom4j.Element;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;

import java.util.Date;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.TimeZone;

/**
 * Represent the data model for one <code>MUCRoom</code> history. Including chat transcript,
 * joining and leaving times.
 * 
 * @author Gaston Dombiak
 */
public final class MUCRoomHistory {

    private static final FastDateFormat UTC_FORMAT = FastDateFormat
            .getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));

    private MUCRoom room;

    private HistoryStrategy historyStrategy;

    private boolean isNonAnonymousRoom;

    public MUCRoomHistory(MUCRoom mucRoom, HistoryStrategy historyStrategy) {
        this.room = mucRoom;
        this.isNonAnonymousRoom = mucRoom.canAnyoneDiscoverJID();
        this.historyStrategy = historyStrategy;
    }

    public void addMessage(Message packet) {
        // Don't keep messages whose sender is the room itself (thus address without resource)
        // unless the message is changing the room's subject
        if ((packet.getFrom() == null || packet.getFrom().toString().length() == 0 ||
                packet.getFrom().equals(room.getRole().getRoleAddress())) &&
                packet.getSubject() == null) {
            return;
        }
        // Do not store messages is strategy is none and message is not changing the room subject
        if (!historyStrategy.isHistoryEnabled()) {
            if (packet.getSubject() == null || packet.getSubject().trim().length() == 0) {
                return;
            }
        }

        // Ignore messages with no subject AND no body
        if ((packet.getSubject() == null || "".equals(packet.getSubject().trim())) &&
                (packet.getBody() == null || "".equals(packet.getBody().trim()))) {
            return;
        }

        Message packetToAdd = packet.createCopy();

        // Check if the room has changed its configuration
        if (isNonAnonymousRoom != room.canAnyoneDiscoverJID()) {
            isNonAnonymousRoom = room.canAnyoneDiscoverJID();
            // Update the "from" attribute of the delay information in the history
            Message message;
            Element delayElement;
            // TODO Make this update in a separate thread
            for (Iterator it = getMessageHistory(); it.hasNext();) {
                message = (Message) it.next();
                delayElement = message.getChildElement("x", "jabber:x:delay");
                if (room.canAnyoneDiscoverJID()) {
                    // Set the Full JID as the "from" attribute
                    try {
                        MUCRole role = room.getOccupant(message.getFrom().getResource());
                        delayElement.addAttribute("from", role.getUserAddress().toString());
                    }
                    catch (UserNotFoundException e) {
                        // Ignore.
                    }
                }
                else {
                    // Set the Room JID as the "from" attribute
                    delayElement.addAttribute("from", message.getFrom().toString());
                }
            }

        }

        // Add the delay information to the message
        Element delayInformation = packetToAdd.addChildElement("x", "jabber:x:delay");
        Date current = new Date();
        delayInformation.addAttribute("stamp", UTC_FORMAT.format(current));
        if (room.canAnyoneDiscoverJID()) {
            // Set the Full JID as the "from" attribute
            try {
                MUCRole role = room.getOccupant(packet.getFrom().getResource());
                delayInformation.addAttribute("from", role.getUserAddress().toString());
            }
            catch (UserNotFoundException e) {
                // Ignore.
            }
        }
        else {
            // Set the Room JID as the "from" attribute
            delayInformation.addAttribute("from", packet.getFrom().toString());
        }
        historyStrategy.addMessage(packetToAdd);
    }

    public Iterator getMessageHistory() {
        return historyStrategy.getMessageHistory();
    }

    /**
     * Obtain the current history to be iterated in reverse mode. This means that the returned list
     * iterator will be positioned at the end of the history so senders of this message must
     * traverse the list in reverse mode.
     * 
     * @return A list iterator of Message objects positioned at the end of the list.
     */
    public ListIterator getReverseMessageHistory() {
        return historyStrategy.getReverseMessageHistory();
    }

    /**
     * Creates a new message and adds it to the history. The new message will be created based on
     * the provided information. This information will likely come from the database when loading
     * the room history from the database.
     *
     * @param senderJID the sender's JID of the message to add to the history.
     * @param nickname the sender's nickname of the message to add to the history.
     * @param sentDate the date when the message was sent to the room.
     * @param subject the subject included in the message.
     * @param body the body of the message.
     */
    public void addOldMessage(String senderJID, String nickname, Date sentDate, String subject,
            String body)
    {
        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());
        }

        // Add the delay information to the message
        Element delayInformation = message.addChildElement("x", "jabber:x:delay");
        delayInformation.addAttribute("stamp", UTC_FORMAT.format(sentDate));
        if (room.canAnyoneDiscoverJID()) {
            // Set the Full JID as the "from" attribute
            delayInformation.addAttribute("from", senderJID);
        }
        else {
            // Set the Room JID as the "from" attribute
            delayInformation.addAttribute("from", room.getRole().getRoleAddress().toString());
        }
        historyStrategy.addMessage(message);
    }

    /**
     * Returns true if there is a message within the history of the room that has changed the
     * room's subject.
     *
     * @return true if there is a message within the history of the room that has changed the
     *         room's subject.
     */
    public boolean hasChangedSubject() {
        return historyStrategy.hasChangedSubject();
    }
}