⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conversation.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            DbConnectionManager.closeConnection(rs, pstmt, con);
        }
        // Add messages of users joining or leaving the group chat conversation
        if (room != null) {
            for (Map.Entry<String, UserParticipations> entry : participants.entrySet()) {
                JID user = new JID(entry.getKey());
                boolean anonymous = false;
                String name;
                try {
                    name = UserNameManager.getUserName(user);
                }
                catch (UserNotFoundException e) {
                    name = user.toBareJID();
                    anonymous = true;
                }
                for (ConversationParticipation participation : entry.getValue().getParticipations()) {
                    if (participation.getJoined() == null) {
                        Log.warn("Found muc participant with no join date in conversation: " + conversationID);
                        continue;
                    }
                    JID jid = new JID(room + "/" + participation.getNickname());
                    String joinBody;
                    String leftBody;
                    if (anonymous) {
                        joinBody = LocaleUtils.getLocalizedString("muc.conversation.joined.anonymous", "monitoring",
                                Arrays.asList(participation.getNickname()));
                        leftBody = LocaleUtils.getLocalizedString("muc.conversation.left.anonymous", "monitoring",
                                Arrays.asList(participation.getNickname()));
                    }
                    else {
                        joinBody = LocaleUtils.getLocalizedString("muc.conversation.joined", "monitoring",
                                Arrays.asList(participation.getNickname(), name));
                        leftBody = LocaleUtils.getLocalizedString("muc.conversation.left", "monitoring",
                                Arrays.asList(participation.getNickname(), name));
                    }
                    messages.add(
                            new ArchivedMessage(conversationID, user, jid, participation.getJoined(), joinBody, true));
                    if (participation.getLeft() != null) {
                        messages.add(new ArchivedMessage(conversationID, user, jid, participation.getLeft(), leftBody,
                                true));
                    }
                }
            }
            // Sort messages by sent date
            Collections.sort(messages, new Comparator<ArchivedMessage>() {
                public int compare(ArchivedMessage o1, ArchivedMessage o2) {
                    return o1.getSentDate().compareTo(o2.getSentDate());
                }
            });
        }
        return messages;
    }

    public String toString() {
        StringBuilder buf = new StringBuilder();
        buf.append("Conversation [").append(conversationID).append("]");
        if (room != null) {
            buf.append(" in room").append(room);
        }
        buf.append(" between ").append(participants);
        buf.append(". started ").append(JiveGlobals.formatDateTime(startDate));
        buf.append(", last active ").append(JiveGlobals.formatDateTime(lastActivity));
        buf.append(". Total messages: ").append(messageCount);
        return buf.toString();
    }

    /**
     * Called when a new message for the conversation is received. Each time a new
     * message is received, the last activity date will be updated and the message
     * count incremented.
     *
     * @param entity JID of the entity that sent the message.
     * @param date   the date the message was sent.
     */
    synchronized void messageReceived(JID entity, Date date) {
        lastActivity = date;
        messageCount++;
    }

    synchronized void participantJoined(JID user, String nickname, long timestamp) {
        // Add the sender of the message as a participant of this conversation. If the sender
        // was already a participant then he/she will appear just once. Rooms are never considered
        // as participants
        UserParticipations userParticipations = participants.get(user.toString());
        if (userParticipations == null) {
            userParticipations = new UserParticipations(true);
            participants.put(user.toString(), userParticipations);
        }
        else {
            // Get last known participation and check that the user has finished it
            ConversationParticipation lastParticipation = userParticipations.getRecentParticipation();
            if (lastParticipation != null && lastParticipation.getLeft() == null) {
                Log.warn("Found user that never left a previous conversation: " + user);
                lastParticipation.participationEnded(new Date(timestamp));
                // Queue storeage of updated participation information
                conversationManager.queueParticipantLeft(this, user, lastParticipation);
            }
        }
        ConversationParticipation newParticipation = new ConversationParticipation(new Date(timestamp), nickname);
        // Add element to the beginning of the list
        userParticipations.addParticipation(newParticipation);
        // If archiving is enabled, insert the conversation into the database (if not persistent yet).
        if (conversationManager.isMetadataArchivingEnabled()) {
            try {
                if (conversationID == -1) {
                    // Save new conversation to the database
                    insertIntoDb();
                }
                else {
                    // Store new participation information
                    insertIntoDb(user, nickname, timestamp);
                }
            }
            catch (Exception e) {
                Log.error(e);
            }
        }
    }

    synchronized void participantLeft(JID user, long timestamp) {
        // Get the list of participations of the specified user
        UserParticipations userParticipations = participants.get(user.toString());
        if (userParticipations == null) {
            Log.warn("Found user that left a conversation but never started it: " + user);
        }
        else {
            // Get last known participation and check that the user has not finished it
            ConversationParticipation currentParticipation = userParticipations.getRecentParticipation();
            if (currentParticipation == null || currentParticipation.getLeft() != null) {
                Log.warn("Found user that left a conversation but never started it: " + user);
            }
            else {
                currentParticipation.participationEnded(new Date(timestamp));
                // Queue storeage of updated participation information
                conversationManager.queueParticipantLeft(this, user, currentParticipation);
            }
        }
    }

    /**
     * Inserts a new conversation into the database.
     *
     * @throws SQLException if an error occurs inserting the conversation.
     */
    private void insertIntoDb() throws SQLException {
        this.conversationID = SequenceManager.nextID(this);
        Connection con = null;
        boolean abortTransaction = false;
        try {
            con = DbConnectionManager.getTransactionConnection();
            PreparedStatement pstmt = con.prepareStatement(INSERT_CONVERSATION);
            pstmt.setLong(1, conversationID);
            pstmt.setString(2, room == null ? null : room.toString());
            pstmt.setInt(3, (external ? 1 : 0));
            pstmt.setLong(4, startDate.getTime());
            pstmt.setLong(5, lastActivity.getTime());
            pstmt.executeUpdate();
            pstmt.close();

            pstmt = con.prepareStatement(INSERT_PARTICIPANT);
            for (Map.Entry<String, UserParticipations> entry : participants.entrySet()) {
                JID user = new JID(entry.getKey());
                for (ConversationParticipation participation : entry.getValue().getParticipations()) {
                    pstmt.setLong(1, conversationID);
                    pstmt.setLong(2, participation.getJoined().getTime());
                    pstmt.setString(3, user.toBareJID());
                    pstmt.setString(4, user.getResource() == null ? " " : user.getResource());
                    pstmt.setString(5, participation.getNickname());
                    pstmt.executeUpdate();
                }
            }
            pstmt.close();
        }
        catch (SQLException sqle) {
            abortTransaction = true;
            throw sqle;
        }
        finally {
            DbConnectionManager.closeTransactionConnection(con, abortTransaction);
        }
    }

    /**
     * Adds a new conversation participant into the database.
     *
     * @param participant the full JID of the participant.
     * @param nickname    nickname of the user in the room.
     * @param joined      timestamp when user joined the conversation.
     * @throws SQLException if an error occurs inserting the conversation.
     */
    private void insertIntoDb(JID participant, String nickname, long joined) throws SQLException {
        Connection con = null;
        try {
            con = DbConnectionManager.getConnection();
            PreparedStatement pstmt = con.prepareStatement(INSERT_PARTICIPANT);
            pstmt.setLong(1, conversationID);
            pstmt.setLong(2, joined);
            pstmt.setString(3, participant.toBareJID());
            pstmt.setString(4, participant.getResource());
            pstmt.setString(5, nickname);
            pstmt.executeUpdate();
            pstmt.close();
        }
        catch (SQLException sqle) {
            throw sqle;
        }
        finally {
            DbConnectionManager.closeConnection(con);
        }
    }

    private void loadFromDb() throws NotFoundException {
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            con = DbConnectionManager.getConnection();
            pstmt = con.prepareStatement(LOAD_CONVERSATION);
            pstmt.setLong(1, conversationID);
            rs = pstmt.executeQuery();
            if (!rs.next()) {
                throw new NotFoundException("Conversation not found: " + conversationID);
            }
            this.room = rs.getString(1) == null ? null : new JID(rs.getString(1));
            this.external = rs.getInt(2) == 1;
            this.startDate = new Date(rs.getLong(3));
            this.lastActivity = new Date(rs.getLong(4));
            this.messageCount = rs.getInt(5);
            rs.close();
            pstmt.close();

            this.participants = new ConcurrentHashMap<String, UserParticipations>();
            pstmt = con.prepareStatement(LOAD_PARTICIPANTS);
            pstmt.setLong(1, conversationID);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                // Rebuild full JID of participant
                String baredJID = rs.getString(1);
                String resource = rs.getString(2);
                JID fullJID = new JID("".equals(resource) ? baredJID : baredJID + "/" + resource);
                // Rebuild joined and left time
                ConversationParticipation participation =
                        new ConversationParticipation(new Date(rs.getLong(4)), rs.getString(3));
                if (rs.getLong(5) > 0) {
                    participation.participationEnded(new Date(rs.getLong(5)));
                }
                // Store participation data
                UserParticipations userParticipations = participants.get(fullJID.toString());
                if (userParticipations == null) {
                    userParticipations = new UserParticipations(room != null);
                    participants.put(fullJID.toString(), userParticipations);
                }
                userParticipations.addParticipation(participation);
            }
        }
        catch (SQLException sqle) {
            Log.error(sqle);
        }
        finally {
            DbConnectionManager.closeConnection(rs, pstmt, con);
        }
    }

    /**
     * Notification message inficating that conversation has finished so remaining participants
     * should be marked that they left the conversation.
     *
     * @param nowDate the date when the conversation was finished
     */
    void conversationEnded(Date nowDate) {
        for (Map.Entry<String, UserParticipations> entry : participants.entrySet()) {
            ConversationParticipation currentParticipation = entry.getValue().getRecentParticipation();
            if (currentParticipation.getLeft() == null) {
                currentParticipation.participationEnded(nowDate);
                // Queue storage of updated participation information
                conversationManager.queueParticipantLeft(this, new JID(entry.getKey()), currentParticipation);
            }
        }
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        ExternalizableUtil.getInstance().writeLong(out, conversationID);
        ExternalizableUtil.getInstance().writeExternalizableMap(out, participants);
        ExternalizableUtil.getInstance().writeBoolean(out, external);
        ExternalizableUtil.getInstance().writeLong(out, startDate.getTime());
        ExternalizableUtil.getInstance().writeLong(out, lastActivity.getTime());
        ExternalizableUtil.getInstance().writeInt(out, messageCount);
        ExternalizableUtil.getInstance().writeBoolean(out, room != null);
        if (room != null) {
            ExternalizableUtil.getInstance().writeSerializable(out, room);
        }
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        MonitoringPlugin plugin = (MonitoringPlugin) XMPPServer.getInstance().getPluginManager().getPlugin(
                "monitoring");
        conversationManager = (ConversationManager) plugin.getModule(ConversationManager.class);


        this.participants = new ConcurrentHashMap<String, UserParticipations>();

        conversationID = ExternalizableUtil.getInstance().readLong(in);
        ExternalizableUtil.getInstance().readExternalizableMap(in, participants, getClass().getClassLoader());
        external = ExternalizableUtil.getInstance().readBoolean(in);
        startDate = new Date(ExternalizableUtil.getInstance().readLong(in));
        lastActivity = new Date(ExternalizableUtil.getInstance().readLong(in));
        messageCount = ExternalizableUtil.getInstance().readInt(in);
        if (ExternalizableUtil.getInstance().readBoolean(in)) {
            room = (JID) ExternalizableUtil.getInstance().readSerializable(in);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -