PresenceManagerImpl.java 8.35 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1 2 3 4 5
/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
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.spi;

14
import org.jivesoftware.messenger.*;
Matt Tucker's avatar
Matt Tucker committed
15 16 17 18
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException;
19 20
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
21
import org.xmpp.packet.JID;
Derek DeMoro's avatar
Derek DeMoro committed
22
import org.xmpp.packet.Presence;
23
import org.xmpp.component.Component;
24 25
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
Matt Tucker's avatar
Matt Tucker committed
26

27 28
import java.util.*;

Matt Tucker's avatar
Matt Tucker committed
29 30 31 32 33 34 35
/**
 * Simple in memory implementation of the PresenceManager interface.
 *
 * @author Iain Shigeoka
 */
public class PresenceManagerImpl extends BasicModule implements PresenceManager {

36 37
    private static final String lastPresenceProp = "lastUnavailablePresence";

38 39 40
    private SessionManager sessionManager;
    private XMPPServer server;
    private PacketDeliverer deliverer;
Matt Tucker's avatar
Matt Tucker committed
41

42
    private InternalComponentManager componentManager;
43

Matt Tucker's avatar
Matt Tucker committed
44 45
    public PresenceManagerImpl() {
        super("Presence manager");
46 47

        // Use component manager for Presence Updates.
48
        componentManager = InternalComponentManager.getInstance();
Matt Tucker's avatar
Matt Tucker committed
49 50
    }

Matt Tucker's avatar
Matt Tucker committed
51
    public boolean isAvailable(User user) {
52
        return sessionManager.getSessionCount(user.getUsername()) > 0;
Matt Tucker's avatar
Matt Tucker committed
53 54 55 56 57 58
    }

    public Presence getPresence(User user) {
        if (user == null) {
            return null;
        }
Matt Tucker's avatar
Matt Tucker committed
59
        Presence presence = null;
Derek DeMoro's avatar
Derek DeMoro committed
60

61
        for (ClientSession session : sessionManager.getSessions(user.getUsername())) {
Derek DeMoro's avatar
Derek DeMoro committed
62 63 64
            if (presence == null) {
                presence = session.getPresence();
            }
65 66 67 68 69 70 71 72 73 74
            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();
                }
Matt Tucker's avatar
Matt Tucker committed
75
            }
Matt Tucker's avatar
Matt Tucker committed
76
        }
Matt Tucker's avatar
Matt Tucker committed
77 78 79 80 81 82 83 84
        return presence;
    }

    public Collection<Presence> getPresences(User user) {
        if (user == null) {
            return null;
        }
        List<Presence> presences = new ArrayList<Presence>();
Derek DeMoro's avatar
Derek DeMoro committed
85

86
        for (ClientSession session : sessionManager.getSessions(user.getUsername())) {
Derek DeMoro's avatar
Derek DeMoro committed
87
            presences.add(session.getPresence());
Matt Tucker's avatar
Matt Tucker committed
88
        }
Matt Tucker's avatar
Matt Tucker committed
89
        return Collections.unmodifiableCollection(presences);
Matt Tucker's avatar
Matt Tucker committed
90 91
    }

92
    public void probePresence(JID prober, JID probee) {
Matt Tucker's avatar
Matt Tucker committed
93
        try {
94
            Component component = getPresenceComponent(probee);
95
            if (server.isLocal(probee)) {
96 97
                // If the probee is a local user then don't send a probe to the contact's server.
                // But instead just send the contact's presence to the prober
98
                if (probee.getNode() != null && !"".equals(probee.getNode())) {
99
                    Collection<ClientSession> sessions =
100
                            sessionManager.getSessions(probee.getNode());
101 102 103 104
                    if (sessions.isEmpty()) {
                        // If the probee is not online then try to retrieve his last unavailable
                        // presence which may contain particular information and send it to the
                        // prober
Matt Tucker's avatar
Matt Tucker committed
105
                        try {
106
                            User probeeUser = UserManager.getInstance().getUser(probee.getNode());
107
                            String presenceXML = probeeUser.getProperties().get(lastPresenceProp);
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
                            if (presenceXML != null) {
                                try {
                                    // Parse the element
                                    Document element = DocumentHelper.parseText(presenceXML);
                                    // Create the presence from the parsed element
                                    Presence presencePacket = new Presence(element.getRootElement());
                                    presencePacket.setFrom(probee.toBareJID());
                                    presencePacket.setTo(prober);
                                    // Send the presence to the prober
                                    deliverer.deliver(presencePacket);
                                }
                                catch (Exception e) {
                                    Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
                                }

                            }
Matt Tucker's avatar
Matt Tucker committed
124
                        }
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
                        catch (UserNotFoundException e) {
                        }
                    }
                    else {
                        // The contact is online so send to the prober all the resources where the
                        // probee is connected
                        for (ClientSession session : sessions) {
                            Presence presencePacket = session.getPresence().createCopy();
                            presencePacket.setFrom(session.getAddress());
                            presencePacket.setTo(prober);
                            try {
                                deliverer.deliver(presencePacket);
                            }
                            catch (Exception e) {
                                Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
                            }
Matt Tucker's avatar
Matt Tucker committed
141 142 143 144
                        }
                    }
                }
            }
145
            else if (component != null) {
146 147
                // If the probee belongs to a component then ask the component to process the
                // probe presence
148 149
                Presence presence = new Presence();
                presence.setType(Presence.Type.probe);
150
                presence.setFrom(prober);
151
                presence.setTo(probee);
152
                component.processPacket(presence);
153
            }
Matt Tucker's avatar
Matt Tucker committed
154
            else {
155 156 157 158
                String serverDomain = server.getServerInfo().getName();
                // Check if the probee may be hosted by this server
                if (!probee.getDomain().contains(serverDomain)) {
                    // TODO Implete when s2s is implemented
Matt Tucker's avatar
Matt Tucker committed
159
                }
160
                else {
161 162 163 164
                    // The probee may be related to a component that has not yet been connected so
                    // we will keep a registry of this presence probe. The component will answer
                    // this presence probe when he becomes online
                    componentManager.addPresenceRequest(prober, probee);
Matt Tucker's avatar
Matt Tucker committed
165 166 167
                }
            }
        }
Derek DeMoro's avatar
Derek DeMoro committed
168
        catch (Exception e) {
Matt Tucker's avatar
Matt Tucker committed
169 170 171 172
            Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
        }
    }

173 174 175 176 177 178
    public void deleteLastUnavailablePresence(String username) {
        if (username == null) {
            return;
        }
        try {
            User probeeUser = UserManager.getInstance().getUser(username);
179
            probeeUser.getProperties().remove(lastPresenceProp);
180 181 182 183 184 185 186 187 188 189 190
        }
        catch (UserNotFoundException e) {
        }
    }

    public void saveLastUnavailablePresence(String username, Presence presence) {
        if (username == null) {
            return;
        }
        try {
            User probeeUser = UserManager.getInstance().getUser(username);
191
            probeeUser.getProperties().put(lastPresenceProp, presence.toXML());
192 193 194 195 196
        }
        catch (UserNotFoundException e) {
        }
    }

Matt Tucker's avatar
Matt Tucker committed
197 198 199 200
    // #####################################################################
    // Module management
    // #####################################################################

201 202 203 204 205
    public void initialize(XMPPServer server) {
        super.initialize(server);
        this.server = server;
        deliverer = server.getPacketDeliverer();
        sessionManager = server.getSessionManager();
Matt Tucker's avatar
Matt Tucker committed
206 207
    }

208
    public Component getPresenceComponent(JID probee) {
209
        // Check for registered components
210
        Component component = componentManager.getComponent(probee.toBareJID());
211
        if (component != null) {
212 213 214 215
            return component;
        }
        return null;
    }
Matt Tucker's avatar
Matt Tucker committed
216
}