ComponentManager.java 3.89 KB
Newer Older
Derek DeMoro's avatar
Derek DeMoro committed
1 2
package org.jivesoftware.messenger;

3 4
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
5
import org.jivesoftware.messenger.spi.BasicServer;
6
import org.jivesoftware.util.StringUtils;
7
import org.xmpp.packet.Packet;
8 9
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
Derek DeMoro's avatar
Derek DeMoro committed
10

11
/**
12 13 14 15
 * Manages the registration and delegation of Components. The ComponentManager
 * is responsible for managing registration and delegation of <code>Components</code>,
 * as well as offering a facade around basic server functionallity such as sending and
 * receiving of packets.
16 17 18
 *
 * @author Derek DeMoro
 */
Derek DeMoro's avatar
Derek DeMoro committed
19
public class ComponentManager {
20

21
    private Map<String, Component> components = new ConcurrentHashMap<String, Component>();
22
    private Map<JID, JID> presenceMap = new ConcurrentHashMap<JID, JID>();
Derek DeMoro's avatar
Derek DeMoro committed
23

24
    private static ComponentManager instance = new ComponentManager();
Derek DeMoro's avatar
Derek DeMoro committed
25 26 27 28 29 30 31


    /**
     * Returns the singleton instance of <CODE>ComponentManager</CODE>,
     * creating it if necessary.
     * <p/>
     *
32
     * @return the singleton instance of <Code>ComponentManager</CODE>
Derek DeMoro's avatar
Derek DeMoro committed
33 34
     */
    public static ComponentManager getInstance() {
35
        return instance;
Derek DeMoro's avatar
Derek DeMoro committed
36 37 38 39 40
    }

    private ComponentManager() {
    }

41 42 43 44 45 46 47 48
    /**
     * Registers a <code>Component</code> with the server and maps
     * to particular jid.
     *
     * @param jid       the jid to map to.
     * @param component the <code>Component</code> to register.
     */
    public void addComponent(String jid, Component component) {
Derek DeMoro's avatar
Derek DeMoro committed
49 50
        jid = validateJID(jid);
        components.put(jid, component);
51 52 53

        // Check for potential interested users.
        checkPresences();
Derek DeMoro's avatar
Derek DeMoro committed
54 55
    }

56 57 58 59 60 61
    /**
     * Removes a <code>Component</code> from the server.
     *
     * @param jid the jid mapped to the particular component.
     */
    public void removeComponent(String jid) {
Derek DeMoro's avatar
Derek DeMoro committed
62 63 64
        components.remove(validateJID(jid));
    }

65 66 67 68 69 70 71 72 73
    /**
     * Retrieves the <code>Component</code> which is mapped
     * to the specified JID.
     *
     * @param jid the jid mapped to the component.
     * @return
     */
    public Component getComponent(String jid) {
        if (components.containsKey(validateJID(jid))) {
Derek DeMoro's avatar
Derek DeMoro committed
74 75 76 77 78
            return components.get(validateJID(jid));
        }
        else {
            String serverName = StringUtils.parseServer(validateJID(jid));
            int index = serverName.indexOf(".");
79
            if (index != -1) {
Derek DeMoro's avatar
Derek DeMoro committed
80 81 82 83 84 85 86
                String serviceName = serverName.substring(0, index);
                jid = serviceName;
            }
        }
        return components.get(validateJID(jid));
    }

87 88
    /**
     * Registers Probeers who have not yet been serviced.
89
     *
90 91 92
     * @param prober the jid probing.
     * @param probee the presence being probed.
     */
93
    public void addPresenceRequest(JID prober, JID probee) {
94 95 96 97 98 99
        presenceMap.put(prober, probee);
    }

    /**
     * Send a packet to the specified recipient. Please note that this sends packets only
     * to outgoing jids and does to the incoming server reader.
100
     *
101 102
     * @param packet the packet to send.
     */
103
    public void sendPacket(Packet packet) {
104
        PacketRouter router;
105 106 107
        router = BasicServer.getInstance().getPacketRouter();
        if (router != null) {
            router.route(packet);
108 109 110 111
        }
    }

    private String validateJID(String jid) {
Derek DeMoro's avatar
Derek DeMoro committed
112 113 114
        jid = jid.trim().toLowerCase();
        return jid;
    }
115

116
    private void checkPresences() {
117 118
        for (JID prober : presenceMap.keySet()) {
            JID probee = presenceMap.get(prober);
119

120
            Component component = getComponent(probee.toBareJID());
121
            if (component != null) {
122 123 124
                Presence presence = new Presence();
                presence.setFrom(prober);
                presence.setTo(probee);
125
                component.processPacket(presence);
126 127 128

                // No reason to hold onto prober reference.
                presenceMap.remove(prober);
129 130 131
            }
        }
    }
132
}