MUCRoomHistory.java 6.79 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1 2 3 4 5
/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
Matt Tucker's avatar
Matt Tucker committed
6
 * Copyright (C) 2004 Jive Software. All rights reserved.
Matt Tucker's avatar
Matt Tucker committed
7
 *
Matt Tucker's avatar
Matt Tucker committed
8 9
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
Matt Tucker's avatar
Matt Tucker committed
10
 */
Matt Tucker's avatar
Matt Tucker committed
11

Matt Tucker's avatar
Matt Tucker committed
12 13 14 15 16 17 18 19 20
package org.jivesoftware.messenger.muc;

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

import org.jivesoftware.messenger.user.UserNotFoundException;
21 22 23
import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
import org.dom4j.Element;
Matt Tucker's avatar
Matt Tucker committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

/**
 * 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 SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
    static {
        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
    }

    private MUCRoom room;

Gaston Dombiak's avatar
Gaston Dombiak committed
40
    private HistoryStrategy historyStrategy;
Matt Tucker's avatar
Matt Tucker committed
41 42 43 44 45 46

    private boolean isNonAnonymousRoom;

    public MUCRoomHistory(MUCRoom mucRoom, HistoryStrategy historyStrategy) {
        this.room = mucRoom;
        this.isNonAnonymousRoom = mucRoom.canAnyoneDiscoverJID();
Gaston Dombiak's avatar
Gaston Dombiak committed
47
        this.historyStrategy = historyStrategy;
Matt Tucker's avatar
Matt Tucker committed
48 49 50 51
    }

    public void addMessage(Message packet) {
        // Don't keep messages whose sender is the room itself (thus address without resource)
52
        // unless the message is changing the room's subject
Gaston Dombiak's avatar
Gaston Dombiak committed
53 54
        if ((packet.getFrom() == null || packet.getFrom().toString().length() == 0 ||
                packet.getFrom().equals(room.getRole().getRoleAddress())) &&
55
                packet.getSubject() == null) {
Matt Tucker's avatar
Matt Tucker committed
56 57
            return;
        }
58
        Message packetToAdd = (Message) packet.createCopy();
Matt Tucker's avatar
Matt Tucker committed
59 60 61 62 63 64 65 66

        // TODO Analyze concurrency (on the LinkList) when adding many messages simultaneously

        // 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;
67
            Element delayElement;
Matt Tucker's avatar
Matt Tucker committed
68 69 70
            // TODO Make this update in a separate thread
            for (Iterator it = getMessageHistory(); it.hasNext();) {
                message = (Message) it.next();
71
                delayElement = message.getChildElement("x", "jabber:x:delay");
Matt Tucker's avatar
Matt Tucker committed
72 73 74
                if (room.canAnyoneDiscoverJID()) {
                    // Set the Full JID as the "from" attribute
                    try {
75 76
                        MUCRole role = room.getOccupant(message.getFrom().getResource());
                        delayElement.addAttribute("from", role.getChatUser().getAddress().toString());
Matt Tucker's avatar
Matt Tucker committed
77 78 79 80 81 82
                    }
                    catch (UserNotFoundException e) {
                    }
                }
                else {
                    // Set the Room JID as the "from" attribute
83
                    delayElement.addAttribute("from", message.getFrom().toString());
Matt Tucker's avatar
Matt Tucker committed
84 85 86 87 88 89
                }
            }

        }

        // Add the delay information to the message
90
        Element delayInformation = packetToAdd.addChildElement("x", "jabber:x:delay");
Matt Tucker's avatar
Matt Tucker committed
91
        Date current = new Date();
92
        delayInformation.addAttribute("stamp", UTC_FORMAT.format(current));
Matt Tucker's avatar
Matt Tucker committed
93 94 95
        if (room.canAnyoneDiscoverJID()) {
            // Set the Full JID as the "from" attribute
            try {
96 97 98
                MUCRole role = room.getOccupant(packet.getFrom().getResource());
                delayInformation.addAttribute("from", role.getChatUser().getAddress()
                        .toString());
Matt Tucker's avatar
Matt Tucker committed
99 100 101 102 103 104
            }
            catch (UserNotFoundException e) {
            }
        }
        else {
            // Set the Room JID as the "from" attribute
105
            delayInformation.addAttribute("from", packet.getFrom().toString());
Matt Tucker's avatar
Matt Tucker committed
106
        }
Gaston Dombiak's avatar
Gaston Dombiak committed
107
        historyStrategy.addMessage(packetToAdd);
Matt Tucker's avatar
Matt Tucker committed
108 109 110
    }

    public Iterator getMessageHistory() {
Gaston Dombiak's avatar
Gaston Dombiak committed
111
        return historyStrategy.getMessageHistory();
Matt Tucker's avatar
Matt Tucker committed
112 113 114 115 116 117 118 119 120 121
    }

    /**
     * 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() {
Gaston Dombiak's avatar
Gaston Dombiak committed
122
        return historyStrategy.getReverseMessageHistory();
Matt Tucker's avatar
Matt Tucker committed
123
    }
124 125 126 127 128 129 130 131 132 133 134 135 136

    /**
     * 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,
137 138 139 140 141 142
            String body)
    {
        Message message = new Message();
        message.setType(Message.Type.groupchat);
        message.setSubject(subject);
        message.setBody(body);
143 144
        // Set the sender of the message
        if (nickname != null && nickname.trim().length() > 0) {
145
            JID roomJID = room.getRole().getRoleAddress();
146
            // Recreate the sender address based on the nickname and room's JID
147
            message.setFrom(new JID(roomJID.getNode(), roomJID.getDomain(),
148 149 150 151
                    nickname));
        }
        else {
            // Set the room as the sender of the message
152
            message.setFrom(room.getRole().getRoleAddress());
153 154 155
        }

        // Add the delay information to the message
156
        Element delayInformation = message.addChildElement("x", "jabber:x:delay");
157
        delayInformation.addAttribute("stamp", UTC_FORMAT.format(sentDate));
158 159
        if (room.canAnyoneDiscoverJID()) {
            // Set the Full JID as the "from" attribute
160
            delayInformation.addAttribute("from", senderJID);
161 162 163
        }
        else {
            // Set the Room JID as the "from" attribute
164
            delayInformation.addAttribute("from", room.getRole().getRoleAddress().toString());
165
        }
166
        historyStrategy.addMessage(message);
167 168 169 170 171 172 173 174 175 176 177 178
    }

    /**
     * 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();
    }
Matt Tucker's avatar
Matt Tucker committed
179
}