summaryrefslogtreecommitdiffstats
blob: 07ac8853b0402f8171b0d1bdf83e52cee104a745 (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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/*
 * 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;
import com.isode.stroke.base.SafeByteArray;
import com.isode.stroke.tls.BlindCertificateTrustChecker;
import com.isode.stroke.filetransfer.FileTransferManager;
import com.isode.stroke.filetransfer.FileTransferManagerImpl;
import com.isode.stroke.jingle.JingleSessionManager;
import com.isode.stroke.filetransfer.DummyFileTransferManager;

/**
 * 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;
    private final JingleSessionManager jingleSessionManager;
    private final FileTransferManager fileTransferManager;
    private final BlindCertificateTrustChecker blindCertificateTrustChecker;
    //private final WhiteboardSessionManager whiteboardSessionManager;
    private final ClientBlockListManager blockListManager;

    public 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 SafeByteArray 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);

        blindCertificateTrustChecker = new BlindCertificateTrustChecker();

        jingleSessionManager = new JingleSessionManager(getIQRouter());
        blockListManager = new ClientBlockListManager(getIQRouter());

        /*whiteboardSessionManager = NULL;
        #ifdef SWIFT_EXPERIMENTAL_WB
            whiteboardSessionManager = new WhiteboardSessionManager(getIQRouter(), getStanzaChannel(), presenceOracle, getEntityCapsProvider());
        #endif*/

    	pubsubManager = new PubSubManagerImpl(getStanzaChannel(), getIQRouter());

        /*#ifdef SWIFT_EXPERIMENTAL_FT
            fileTransferManager = new FileTransferManagerImpl(
                    getJID(),
                    jingleSessionManager,
                    getIQRouter(),
                    getEntityCapsProvider(),
                    presenceOracle,
                    getNetworkFactories().getConnectionFactory(),
                    getNetworkFactories().getConnectionServerFactory(),
                    getNetworkFactories().getTimerFactory(),
                    getNetworkFactories().getDomainNameResolver(),
                    getNetworkFactories().getNetworkEnvironment(),
                    getNetworkFactories().getNATTraverser(),
                    getNetworkFactories().getCryptoProvider());
        #else*/
        fileTransferManager = new DummyFileTransferManager();
        //#endif
    }

    /**
     * Constructs a client for the given JID with the given password.
     *
     * \param storages The interfaces for storing cache information etc. If 
     *  this is NULL,
     *  all data will be stored in memory (and be lost on shutdown)
     */
    public  Client(final JID jid, final SafeByteArray 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;
    }

    /** 
     * Returns a representation of the roster.
     *
     * The roster is initially empty. To populate it, call requestRoster(),
     * which will request the roster from the server. When the roster has
     * been requested, it will also be kept up to date when it is updated on
     * the server side.
     *
     * This pointer remains the same across the lifetime of Client. All
     * changes to the roster (e.g. after the initial roster request, or after
     * subsequent roster updates) are notified through the XMPPRoster's
     * signals.
     *
     * \see requestRoster()
     */
    public XMPPRoster getRoster() {
    	return roster;
    }

    public void setSoftwareVersion(final String name, final String version) {
        setSoftwareVersion(name, version, "");
    }

    /**
     * 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);
    }

    /**
     * Requests the roster from the server.
     *
     * \see getRoster()
     */
    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 ClientBlockListManager getClientBlockListManager() {
        return blockListManager;
    }

    /**
     * Returns a FileTransferManager for the client. This is only available after the onConnected 
     * signal has been fired.
     *
     * WARNING: File transfer will only work if Swiften is built in 'experimental' mode.
     */
    public FileTransferManager getFileTransferManager() {
        return fileTransferManager;
    }

    /**
     * Configures the client to always trust a non-validating
     * TLS certificate from the server.
     * This is equivalent to setting a BlindCertificateTrustChecker
     * using setCertificateTrustChecker().
     */
    public void setAlwaysTrustCertificates() {
        setCertificateTrustChecker(blindCertificateTrustChecker);
    }

    //TO PORT
    /*public WhiteboardSessionManager getWhiteboardSessionManager() {
        return whiteboardSessionManager;
    }*/

    public VCardManager getVCardManager() {
    	return vcardManager;
    }
    
    public AvatarManager getAvatarManager() {
    	return avatarManager;
    }
    
    private Storages getStorages()  {
    	if (storages != null) {
    		return storages;
    	}
    	return memoryStorages;
    }

    protected void handleConnected() {
        discoManager.handleConnected();
    }

    public PresenceSender getPresenceSender() {
        return discoManager.getPresenceSender();
    }

    public EntityCapsProvider getEntityCapsProvider() {
        return entityCapsManager;
    }

    
}