presenceupdatehandler.java

来自「基于Jabber协议的即时消息服务器」· Java 代码 · 共 474 行 · 第 1/2 页

JAVA
474
字号
     * <p/>
     * Is there a safe way to cache the query results while maintaining
     * integrity with roster changes?
     *
     * @param update The update to broadcast
     */
    private void broadcastUpdate(Presence update) throws PacketException {
        if (update.getFrom() == null) {
            return;
        }
        if (localServer.isLocal(update.getFrom())) {
            // Do nothing if roster service is disabled
            if (!RosterManager.isRosterServiceEnabled()) {
                return;
            }
            // Local updates can simply run through the roster of the local user
            String name = update.getFrom().getNode();
            try {
                if (name != null && !"".equals(name)) {
                    Roster roster = rosterManager.getRoster(name);
                    roster.broadcastPresence(update);
                }
            }
            catch (UserNotFoundException e) {
                Log.warn("Presence being sent from unknown user " + name, e);
            }
            catch (PacketException e) {
                Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
            }
        }
        else {
            // Foreign updates will do a reverse lookup of entries in rosters
            // on the server
            Log.warn("Presence requested from server "
                    + localServer.getServerInfo().getName()
                    + " by unknown user: " + update.getFrom());
            /*
            Connection con = null;
            PreparedStatement pstmt = null;
            try {

                pstmt = con.prepareStatement(GET_ROSTER_SUBS);
                pstmt.setString(1, update.getSender().toBareString().toLowerCase());
                ResultSet rs = pstmt.executeQuery();
                while (rs.next()){
                    long userID = rs.getLong(1);
                    try {
                        User user = server.getUserManager().getUser(userID);

                        update.setRecipient(user.getAddress());
                        server.getSessionManager().userBroadcast(user.getUsername(),
                                                                update.getPacket());
                    } catch (UserNotFoundException e) {
                        Log.error(LocaleUtils.getLocalizedString("admin.error"),e);
                    } catch (UnauthorizedException e) {
                        Log.error(LocaleUtils.getLocalizedString("admin.error"),e);
                    }
                }
            }
            catch (SQLException e) {
                Log.error(LocaleUtils.getLocalizedString("admin.error"),e);
            }
            */
        }
    }

    /**
     * Notification method sent to this handler when a user has sent a directed
     * presence to an entity. If the sender of the presence is local (to this server)
     * and the target entity does not belong to the user's roster then update the
     * registry of sent directed presences by the user.
     *
     * @param update  the directed Presence sent by the user to an entity.
     * @param handler the handler that routed the presence to the entity.
     * @param jid     the jid that the handler has processed
     */
    public void directedPresenceSent(Presence update, ChannelHandler handler, String jid) {
        if (update.getFrom() == null) {
            return;
        }
        if (localServer.isLocal(update.getFrom())) {
            boolean keepTrack = false;
            WeakHashMap<ChannelHandler, Set<String>> map;
            String name = update.getFrom().getNode();
            if (name != null && !"".equals(name)) {
                // Keep track of all directed presences if roster service is disabled
                if (!RosterManager.isRosterServiceEnabled()) {
                    keepTrack = true;
                }
                else {
                    try {
                        Roster roster = rosterManager.getRoster(name);
                        // If the directed presence was sent to an entity that is not in the user's
                        // roster, keep a registry of this so that when the user goes offline we
                        // will be able to send the unavailable presence to the entity
                        RosterItem rosterItem = null;
                        try {
                            rosterItem = roster.getRosterItem(update.getTo());
                        }
                        catch (UserNotFoundException e) {}
                        if (rosterItem == null ||
                                RosterItem.SUB_NONE == rosterItem.getSubStatus() ||
                                RosterItem.SUB_TO == rosterItem.getSubStatus()) {
                            keepTrack = true;
                        }
                    }
                    catch (UserNotFoundException e) {
                        Log.warn("Presence being sent from unknown user " + name, e);
                    }
                    catch (PacketException e) {
                        Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
                    }
                }
            }
            else if (update.getFrom().getResource() != null){
                // Keep always track of anonymous users directed presences
                keepTrack = true;
            }
            if (keepTrack) {
                map = directedPresences.get(update.getFrom().toString());
                if (map == null) {
                    // We are using a set to avoid duplicate jids in case the user
                    // sends several directed presences to the same handler. The Map also
                    // ensures that if the user sends several presences to the same handler
                    // we will have only one entry in the Map
                    map = new WeakHashMap<ChannelHandler, Set<String>>();
                    map.put(handler, new ConcurrentHashSet<String>());
                    directedPresences.put(update.getFrom().toString(), map);
                }
                if (Presence.Type.unavailable.equals(update.getType())) {
                    // It's a directed unavailable presence
                    if (handler instanceof ClientSession) {
                        // Client sessions will receive only presences to the same JID (the
                        // address of the session) so remove the handler from the map
                        map.remove(handler);
                        if (map.isEmpty()) {
                            // Remove the user from the registry since the list of directed
                            // presences is empty
                            directedPresences.remove(update.getFrom().toString());
                        }
                    }
                    else {
                        // A service may receive presences for many JIDs so in this case we
                        // just need to remove the jid that has received a directed
                        // unavailable presence
                        Set<String> jids = map.get(handler);
                        if (jids != null) {
                            jids.remove(jid);
                            if (jids.isEmpty()) {
                                map.remove(handler);
                                if (map.isEmpty()) {
                                    // Remove the user from the registry since the list of directed
                                    // presences is empty
                                    directedPresences.remove(update.getFrom().toString());
                                }
                            }
                        }

                    }
                }
                else {
                    // Add the handler to the list of handler that processed the directed
                    // presence sent by the user. This handler will be used to send
                    // the unavailable presence when the user goes offline
                    if (map.get(handler) == null) {
                        map.put(handler, new ConcurrentHashSet<String>());
                    }
                    map.get(handler).add(jid);
                }
            }
        }
    }

    /**
     * Sends an unavailable presence to the entities that received a directed (available) presence
     * by the user that is now going offline.
     *
     * @param update the unavailable presence sent by the user.
     */
    private void broadcastUnavailableForDirectedPresences(Presence update) {
        if (update.getFrom() == null) {
            return;
        }
        if (localServer.isLocal(update.getFrom())) {
            // Remove the registry of directed presences of this user
            Map<ChannelHandler, Set<String>> map = directedPresences.remove(update.getFrom().toString());
            if (map != null) {
                // Iterate over all the entities that the user sent a directed presence
                for (ChannelHandler handler : new HashSet<ChannelHandler>(map.keySet())) {
                    Set<String> jids = map.get(handler);
                    if (jids == null) {
                        continue;
                    }
                    for (String jid : jids) {
                        Presence presence = update.createCopy();
                        presence.setTo(new JID(jid));
                        try {
                            handler.process(presence);
                        }
                        catch (UnauthorizedException ue) {
                            Log.error(ue);
                        }
                    }
                }
            }
        }
    }

    public boolean hasDirectPresence(Session session, JID recipientJID) {
        Map<ChannelHandler, Set<String>> map =
                directedPresences.get(session.getAddress().toString());
        if (map != null) {
            String recipient = recipientJID.toBareJID();
            for (Set<String> fullJIDs : map.values()) {
                for (String fullJID : fullJIDs) {
                    if (fullJID.contains(recipient)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void initialize(XMPPServer server) {
        super.initialize(server);
        localServer = server;
        rosterManager = server.getRosterManager();
        presenceManager = server.getPresenceManager();
        deliverer = server.getPacketDeliverer();
        messageStore = server.getOfflineMessageStore();
        sessionManager = server.getSessionManager();
        userManager = server.getUserManager();
    }

}

⌨️ 快捷键说明

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