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

📄 presencemanagerimpl.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * $RCSfile: PresenceManagerImpl.java,v $
 * $Revision: 3128 $
 * $Date: 2005-11-30 15:31:54 -0300 (Wed, 30 Nov 2005) $
 *
 * Copyright (C) 2004-2007 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, or a commercial license
 * agreement with Jive.
 */

package org.jivesoftware.openfire.spi;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.component.InternalComponentManager;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.openfire.handler.PresenceUpdateHandler;
import org.jivesoftware.openfire.privacy.PrivacyList;
import org.jivesoftware.openfire.privacy.PrivacyListManager;
import org.jivesoftware.openfire.roster.Roster;
import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.cache.Cache;
import org.jivesoftware.util.cache.CacheFactory;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;

import java.sql.Connection;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;

/**
 * Simple in memory implementation of the PresenceManager interface.
 *
 * @author Iain Shigeoka
 */
public class PresenceManagerImpl extends BasicModule implements PresenceManager {

    private static final String LOAD_OFFLINE_PRESENCE =
            "SELECT offlinePresence, offlineDate FROM jivePresence WHERE username=?";
    private static final String INSERT_OFFLINE_PRESENCE =
            "INSERT INTO jivePresence(username, offlinePresence, offlineDate) VALUES(?,?,?)";
    private static final String DELETE_OFFLINE_PRESENCE =
            "DELETE FROM jivePresence WHERE username=?";

    private static final String NULL_STRING = "NULL";
    private static final long NULL_LONG = -1L;

    private RoutingTable routingTable;
    private SessionManager sessionManager;
    private UserManager userManager;
    private RosterManager rosterManager;
    private XMPPServer server;
    private PacketDeliverer deliverer;
    private PresenceUpdateHandler presenceUpdateHandler;

    private InternalComponentManager componentManager;

    private Cache<String, Long> lastActivityCache;
    private Cache<String, String> offlinePresenceCache;

    public PresenceManagerImpl() {
        super("Presence manager");
    }

    public boolean isAvailable(User user) {
        return sessionManager.getActiveSessionCount(user.getUsername()) > 0;
    }

    public Presence getPresence(User user) {
        if (user == null) {
            return null;
        }
        Presence presence = null;

        for (ClientSession session : sessionManager.getSessions(user.getUsername())) {
            if (presence == null) {
                presence = session.getPresence();
            }
            else {
                // Get the ordinals of the presences to compare. If no ordinal is available then
                // assume a value of -1
                int o1 = presence.getShow() != null ? presence.getShow().ordinal() : -1;
                int o2 = session.getPresence().getShow() != null ?
                        session.getPresence().getShow().ordinal() : -1;
                // Compare the presences' show ordinals
                if (o1 > o2) {
                    presence = session.getPresence();
                }
            }
        }
        return presence;
    }

    public Collection<Presence> getPresences(String username) {
        if (username == null) {
            return null;
        }
        List<Presence> presences = new ArrayList<Presence>();

        for (ClientSession session : sessionManager.getSessions(username)) {
            presences.add(session.getPresence());
        }
        return Collections.unmodifiableCollection(presences);
    }

    public String getLastPresenceStatus(User user) {
        String username = user.getUsername();
        String presenceStatus = null;
        String presenceXML = offlinePresenceCache.get(username);
        if (presenceXML == null) {
            loadOfflinePresence(username);
        }
        presenceXML = offlinePresenceCache.get(username);
        if (presenceXML != null) {
            // If the cached answer is no data, return null.
            if (presenceXML.equals(NULL_STRING)) {
                return null;
            }
            // Otherwise, parse out the status from the XML.
            try {
                // Parse the element
                Document element = DocumentHelper.parseText(presenceXML);
                presenceStatus = element.getRootElement().elementTextTrim("status");
            }
            catch (DocumentException e) {
                Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
            }
        }
        return presenceStatus;
    }

    public long getLastActivity(User user) {
        String username = user.getUsername();
        long lastActivity = NULL_LONG;
        Long offlineDate = lastActivityCache.get(username);
        if (offlineDate == null) {
            loadOfflinePresence(username);
        }
        offlineDate = lastActivityCache.get(username);
        if (offlineDate != null) {
            // If the cached answer is no data, return -1.
            if (offlineDate == NULL_LONG) {
                return NULL_LONG;
            }
            else {
                try {
                    lastActivity = (System.currentTimeMillis() - offlineDate);
                }
                catch (NumberFormatException e) {
                    Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
                }
            }
        }
        return lastActivity;
    }

    public void userAvailable(Presence presence) {
        // Delete the last unavailable presence of this user since the user is now
        // available. Only perform this operation if this is an available presence sent to
        // THE SERVER and the presence belongs to a local user.
        if (presence.getTo() == null && server.isLocal(presence.getFrom())) {
            String username = presence.getFrom().getNode();
            if (username == null || !userManager.isRegisteredUser(username)) {
                // Ignore anonymous users
                return;
            }

            // Optimization: only delete the unavailable presence information if this
            // is the first session created on the server.
            if (sessionManager.getSessionCount(username) > 1) {
                return;
            }

            Connection con = null;
            PreparedStatement pstmt = null;
            try {
                con = DbConnectionManager.getConnection();
                pstmt = con.prepareStatement(DELETE_OFFLINE_PRESENCE);
                pstmt.setString(1, username);
                pstmt.execute();
            }
            catch (SQLException sqle) {
                Log.error(sqle);
            }
            finally {
                DbConnectionManager.closeConnection(pstmt, con);
            }

            // Remove data from cache.
            offlinePresenceCache.remove(username);
            lastActivityCache.remove(username);
        }
    }

    public void userUnavailable(Presence presence) {
        // Only save the last presence status and keep track of the time when the user went
        // offline if this is an unavailable presence sent to THE SERVER and the presence belongs
        // to a local user.
        if (presence.getTo() == null && server.isLocal(presence.getFrom())) {
            String username = presence.getFrom().getNode();
            if (username == null || !userManager.isRegisteredUser(username)) {
                // Ignore anonymous users
                return;
            }

            // If the user has any remaining sessions, don't record the offline info.
            if (sessionManager.getActiveSessionCount(username) > 0) {
                return;
            }

            String offlinePresence = null;
            // Save the last unavailable presence of this user if the presence contains any
            // child element such as <status>.
            if (!presence.getElement().elements().isEmpty()) {
                offlinePresence = presence.toXML();
            }
            // Keep track of the time when the user went offline
            java.util.Date offlinePresenceDate = new java.util.Date();

            boolean addedToCache;
            if (offlinePresence == null) {
                addedToCache = !NULL_STRING.equals(offlinePresenceCache.put(username, NULL_STRING));
            }
            else {
                addedToCache = !offlinePresence.equals(offlinePresenceCache.put(username, offlinePresence));
            }
            if (!addedToCache) {
                return;
            }
            lastActivityCache.put(username, offlinePresenceDate.getTime());

            // Insert data into the database.
            Connection con = null;
            PreparedStatement pstmt = null;
            try {
                con = DbConnectionManager.getConnection();
                pstmt = con.prepareStatement(INSERT_OFFLINE_PRESENCE);
                pstmt.setString(1, username);
                if (offlinePresence != null) {
                    DbConnectionManager.setLargeTextField(pstmt, 2, offlinePresence);
                }
                else {
                    pstmt.setNull(2, Types.VARCHAR);
                }
                pstmt.setString(3, StringUtils.dateToMillis(offlinePresenceDate));
                pstmt.execute();
            }
            catch (SQLException sqle) {
                Log.error("Error storing offline presence of user: " + username, sqle);
            }

⌨️ 快捷键说明

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