PresenceRouter.java 4.78 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1 2 3 4
/**
 * $RCSfile$
 * $Revision$
 * $Date$
Matt Tucker's avatar
Matt Tucker committed
5
 *
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
package org.jivesoftware.messenger;

Derek DeMoro's avatar
Derek DeMoro committed
14
import org.xmpp.packet.Presence;
15 16 17 18 19 20 21 22
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.jivesoftware.messenger.handler.PresenceUpdateHandler;
import org.jivesoftware.messenger.handler.PresenceSubscribeHandler;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.LocaleUtils;
Derek DeMoro's avatar
Derek DeMoro committed
23

Matt Tucker's avatar
Matt Tucker committed
24 25 26 27 28 29 30 31 32
/**
 * <p>Route presence packets throughout the server.</p>
 * <p>Routing is based on the recipient and sender addresses. The typical
 * packet will often be routed twice, once from the sender to some internal
 * server component for handling or processing, and then back to the router
 * to be delivered to it's final destination.</p>
 *
 * @author Iain Shigeoka
 */
33 34 35 36 37 38 39 40 41 42 43 44 45 46
public class PresenceRouter extends BasicModule {

    private RoutingTable routingTable;
    private PresenceUpdateHandler updateHandler;
    private PresenceSubscribeHandler subscribeHandler;
    private SessionManager sessionManager;

    /**
     * Constructs a presence router.
     */
    public PresenceRouter() {
        super("XMPP Presence Router");
    }

Matt Tucker's avatar
Matt Tucker committed
47
    /**
48
     * Routes presence packets.
Matt Tucker's avatar
Matt Tucker committed
49
     *
50 51
     * @param packet the packet to route.
     * @throws NullPointerException if the packet is null.
Matt Tucker's avatar
Matt Tucker committed
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
    public void route(Presence packet) {
        if (packet == null) {
            throw new NullPointerException();
        }
        Session session = sessionManager.getSession(packet.getFrom());
        if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
            handle(packet);
        }
        else {
            packet.setTo(session.getAddress());
            packet.setFrom((JID)null);
            packet.setError(PacketError.Condition.not_authorized);
            try {
                session.process(packet);
            }
            catch (UnauthorizedException ue) {
                Log.error(ue);
            }
        }
    }

    private void handle(Presence packet) {
        JID recipientJID = packet.getTo();
        try {
            Presence.Type type = packet.getType();
            // Presence updates (null is 'available')
            if (type == null || Presence.Type.unavailable == type) {
                // check for local server target
                if (recipientJID == null
                        || recipientJID.getDomain() == null
                        || "".equals(recipientJID.getDomain())
                        || (recipientJID.getNode() == null && recipientJID.getResource() == null)) {

                    updateHandler.process(packet);
                }
                else {
                    // The user sent a directed presence to an entity
                    ChannelHandler handler = routingTable.getRoute(recipientJID);
                    handler.process(packet);
                    // Notify the PresenceUpdateHandler of the directed presence
93
                    updateHandler.directedPresenceSent(packet, handler, recipientJID.toString());
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
                }

            }
            else if (Presence.Type.subscribe == type // presence subscriptions
                    || Presence.Type.unsubscribe == type
                    || Presence.Type.subscribed == type
                    || Presence.Type.unsubscribed == type)
            {
                subscribeHandler.process(packet);
            }
            else {
                // It's an unknown or ERROR type, just deliver it because there's nothing else to do with it
                routingTable.getRoute(recipientJID).process(packet);
            }

        }
        catch (NoSuchRouteException e) {
            // Do nothing, presence to unreachable routes are dropped
        }
        catch (Exception e) {
            Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e);
            try {
                Session session = sessionManager.getSession(packet.getFrom());
                if (session != null) {
                    Connection conn = session.getConnection();
                    if (conn != null) {
                        conn.close();
                    }
                }
            }
            catch (UnauthorizedException e1) {
                // do nothing
            }
        }
    }

    public void initialize(XMPPServer server) {
        super.initialize(server);
        routingTable = server.getRoutingTable();
        updateHandler = server.getPresenceUpdateHandler();
        subscribeHandler = server.getPresenceSubscribeHandler();
        sessionManager = server.getSessionManager();
    }
Matt Tucker's avatar
Matt Tucker committed
137
}