summaryrefslogtreecommitdiffstats
blob: 693822552c41946f02a5a5e19d8e4da94b5454c4 (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
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*
 * Copyright (c) 2010-2015, Isode Limited, London, England.
 * All rights reserved.
 */
package com.isode.stroke.client;

import com.isode.stroke.avatars.AvatarManager;
import com.isode.stroke.avatars.AvatarManagerImpl;
import com.isode.stroke.disco.CapsManager;
import com.isode.stroke.disco.ClientDiscoManager;
import com.isode.stroke.disco.EntityCapsManager;
import com.isode.stroke.disco.EntityCapsProvider;
import com.isode.stroke.elements.Presence;
import com.isode.stroke.jid.JID;
import com.isode.stroke.muc.MUCManager;
import com.isode.stroke.muc.MUCRegistry;
import com.isode.stroke.network.NetworkFactories;
import com.isode.stroke.presence.DirectedPresenceSender;
import com.isode.stroke.presence.PresenceOracle;
import com.isode.stroke.presence.PresenceSender;
import com.isode.stroke.presence.StanzaChannelPresenceSender;
import com.isode.stroke.presence.SubscriptionManager;
import com.isode.stroke.pubsub.PubSubManager;
import com.isode.stroke.pubsub.PubSubManagerImpl;
import com.isode.stroke.queries.responders.SoftwareVersionResponder;
import com.isode.stroke.roster.XMPPRoster;
import com.isode.stroke.roster.XMPPRosterController;
import com.isode.stroke.roster.XMPPRosterImpl;
import com.isode.stroke.signals.Signal1;
import com.isode.stroke.vcards.VCardManager;

/**
 * Provides the core functionality for writing XMPP client software.
 *
 * Besides connecting to an XMPP server, this class also provides interfaces for
 * performing most tasks on the XMPP network.
 */

public class Client extends CoreClient {

    private final MUCManager mucManager;
    private final MUCRegistry mucRegistry;
    private final DirectedPresenceSender directedPresenceSender; //NOPMD, this is not better as a local variable
    private final StanzaChannelPresenceSender stanzaChannelPresenceSender; //NOPMD, this is not better as a local variable
    private final SoftwareVersionResponder softwareVersionResponder;
    private final PubSubManager pubSubManager;
    private final XMPPRosterImpl roster;
    private final XMPPRosterController rosterController;
    private final PresenceOracle presenceOracle;
    private final Storages storages;
    private final MemoryStorages memoryStorages;
    private final VCardManager vcardManager;
    private final CapsManager capsManager;
    private final EntityCapsManager entityCapsManager;
    private final NickManager nickManager;
    private final NickResolver nickResolver;
    private final SubscriptionManager subscriptionManager;
    private final ClientDiscoManager discoManager;
    private final AvatarManager avatarManager;

    final Signal1<Presence> onPresenceChange = new Signal1<Presence>();

    /**
     * Constructor.
     * 
     * @param eventLoop Event loop used by the class, must not be null. The
     *            Client creates threads to do certain tasks. However, it
     *            posts events that it expects to be done in the application's
     *            main thread to this eventLoop. The application should
     *            use an appropriate EventLoop implementation for the application type. This
     *            EventLoop is just a way for the Client to pass these
     *            events back to the main thread, and should not be used by the
     *            application for its own purposes.
     * @param jid User JID used to connect to the server, must not be null
     * @param password User password to use, must not be null
     * @param networkFactories An implementation of network interaction, must
     *            not be null.
     */
    public  Client(final JID jid, final String password, final NetworkFactories networkFactories, Storages storages) {
        super(jid, password, networkFactories);
        
        this.storages = storages;
        memoryStorages = new MemoryStorages(networkFactories.getCryptoProvider());
        
        softwareVersionResponder = new SoftwareVersionResponder(getIQRouter());
        softwareVersionResponder.start();
        
        roster = new XMPPRosterImpl();
    	rosterController = new XMPPRosterController(getIQRouter(), roster, getStorages().getRosterStorage());

    	subscriptionManager = new SubscriptionManager(getStanzaChannel());
    	
    	presenceOracle = new PresenceOracle(getStanzaChannel());
    	presenceOracle.onPresenceChange.connect(onPresenceChange);

        stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel());
        directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender);
        discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories.getCryptoProvider());

        mucRegistry = new MUCRegistry();
        mucManager = new MUCManager(getStanzaChannel(), getIQRouter(), directedPresenceSender, mucRegistry);

        vcardManager = new VCardManager(jid, getIQRouter(), getStorages().getVCardStorage());
    	avatarManager = new AvatarManagerImpl(vcardManager, getStanzaChannel(), getStorages().getAvatarStorage(), networkFactories.getCryptoProvider(), mucRegistry);
        capsManager = new CapsManager(getStorages().getCapsStorage(), getStanzaChannel(), getIQRouter(), networkFactories.getCryptoProvider());
        entityCapsManager = new EntityCapsManager(capsManager, getStanzaChannel());

    	nickManager = new NickManagerImpl(jid.toBare(), vcardManager);
    	nickResolver = new NickResolver(jid.toBare(), roster, vcardManager, mucRegistry);

    	pubSubManager = new PubSubManagerImpl(getStanzaChannel(), getIQRouter());
    }
    
    public  Client(final JID jid, final String password, final NetworkFactories networkFactories) {
        this(jid, password, networkFactories, null);
    }

    /**
     * Get the manager for multi user chat rooms
     * @return MUC manager, not null
     */
    public MUCManager getMUCManager() {
        return mucManager;
    }

    /**
     * Get the registry for multi user chat rooms
     * @return MUC registry, not null
     */
    public MUCRegistry getMUCRegistry() {
        return mucRegistry;
    }
    
	/**
     * Get the manager for publish-subscribe
     * @return PubSub manager, not null
     */
    public PubSubManager getPubSubManager() {
        return pubSubManager;
    }
    
    public XMPPRoster getRoster() {
    	return roster;
    }
    
    /**
     * Sets the software version of the client.                  
     *
     * This will be used to respond to version queries from other entities.
     */
    public void setSoftwareVersion(final String name, final String version, final String os) {
        softwareVersionResponder.setVersion(name, version, os);
    }


    public void requestRoster() {
    	// FIXME: We should set this once when the session is finished, but there
    	// is currently no callback for this
    	if (getSession() != null) {
    		rosterController.setUseVersioning(getSession().getRosterVersioningSuported());
    	}
    	rosterController.requestRoster();
    }

    public Presence getLastPresence(final JID jid) {
    	return presenceOracle.getLastPresence(jid);
    }

    public Presence getHighestPriorityPresence(final JID bareJID) {
    	return presenceOracle.getHighestPriorityPresence(bareJID);
    }

    public PresenceOracle getPresenceOracle() {
		return presenceOracle;
	}
    
	public NickManager getNickManager() {
    	return nickManager;
    }

    public NickResolver getNickResolver() {
    	return nickResolver;
    }
    
    public SubscriptionManager getSubscriptionManager() {
    	return subscriptionManager;
    }
    
    public ClientDiscoManager getDiscoManager() {
        return discoManager;
    }
    
    public VCardManager getVCardManager() {
    	return vcardManager;
    }
    
    public AvatarManager getAvatarManager() {
    	return avatarManager;
    }
    
    private Storages getStorages()  {
    	if (storages != null) {
    		return storages;
    	}
    	return memoryStorages;
    }
    
    public PresenceSender getPresenceSender() {
        return discoManager.getPresenceSender();
    }

    public EntityCapsProvider getEntityCapsProvider() {
        return entityCapsManager;
    }

    
}