summaryrefslogtreecommitdiffstats
blob: 1938bec51380fd59df2ab4635fdf8d96e3192db8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * Copyright (c) 2012, Isode Limited, London, England.
 * All rights reserved.
 */
/*
 * Copyright (c) 2010 Remko Tronçon
 * All rights reserved.
 */
package com.isode.stroke.presence;

import java.util.HashSet;
import java.util.Set;

import com.isode.stroke.elements.Presence;
import com.isode.stroke.jid.JID;

/**
 * Class representing a directed presence sender.
 * DirectedPresenceSender tracks who you want to send directed presence to and sends the
 * presence to the directed targets.
 *
 */
public class DirectedPresenceSender implements PresenceSender {

    public enum SendPresence {
        AndSendPresence, 
        DontSendPresence
    };

    private Presence lastSentUndirectedPresence_;
    private PresenceSender sender_;
    private Set<JID> directedPresenceReceivers_ = new HashSet<JID>();

    /**
     * Constructor
     * @param sender PresenceSender, not null
     */
    public DirectedPresenceSender(PresenceSender sender) {
        sender_ = sender;
    }

    /**
     * Send future broadcast presence also to this JID.
     * @param jid Non-roster JID to receive global presence updates.
     * @param sendPresence Also send the current global presence immediately.     
     */

    public void addDirectedPresenceReceiver(JID jid, SendPresence sendPresence) {
        directedPresenceReceivers_.add(jid);
        if (SendPresence.AndSendPresence.equals(sendPresence) && sender_.isAvailable()) {
            if (lastSentUndirectedPresence_ != null && 
                    Presence.Type.Available.equals(lastSentUndirectedPresence_.getType())) {
                Presence presenceCopy = new Presence(lastSentUndirectedPresence_);
                presenceCopy.setTo(jid);
                sender_.sendPresence(presenceCopy);
            }
        }
    }

    /**
     * Remove the sender from the list of JIDs to whom broadcast presence will be sent.
     * @param jid  Non-roster JID to stop receiving global presence updates.
     * @param sendPresence Also send presence type=unavailable immediately to jid.
     */
    public void removeDirectedPresenceReceiver(JID jid, SendPresence sendPresence) {
        directedPresenceReceivers_.remove(jid);
        if (SendPresence.AndSendPresence.equals(sendPresence) && sender_.isAvailable()) {
            Presence presence = new Presence();
            presence.setType(Presence.Type.Unavailable);
            presence.setTo(jid);
            sender_.sendPresence(presence);
        }
    }

    @Override
    public void sendPresence(Presence presence) {
        if (!sender_.isAvailable()) {
            return;
        }
        sender_.sendPresence(presence);
        if (!presence.getTo().isValid()) {
            Presence presenceCopy = new Presence(presence);
            for(JID jid : directedPresenceReceivers_) {
                presenceCopy.setTo(jid);
                sender_.sendPresence(presenceCopy);
            }

            lastSentUndirectedPresence_ = presence;
        }
    }

    /**
     * Gets either the last broadcast presence, or an empty stanza if none has been sent.
     * @return presence, not null 
     * 
     */
    public Presence getLastSentUndirectedPresence(){
        if(lastSentUndirectedPresence_ == null) {
            return null;
        }else {
            return new Presence(lastSentUndirectedPresence_);
        }
    }

    @Override
    public boolean isAvailable() {
        return sender_.isAvailable();
    }
}