~vaifrax/inkscape/bugfix170049

« back to all changes in this revision

Viewing changes to src/jabber_whiteboard/session-manager.h

  • Committer: mental
  • Date: 2006-01-16 02:36:01 UTC
  • Revision ID: mental@users.sourceforge.net-20060116023601-wkr0h7edl5veyudq
moving trunk for module inkscape

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Whiteboard session manager
 
3
 *
 
4
 * Authors: 
 
5
 * David Yip <yipdw@rose-hulman.edu>
 
6
 *
 
7
 * Copyright (c) 2005 Authors
 
8
 *
 
9
 * Released under GNU GPL, read the file 'COPYING' for more information
 
10
 */
 
11
 
 
12
#ifndef __SESSION_MANAGER_H__
 
13
#define __SESSION_MANAGER_H__
 
14
 
 
15
#include <glibmm.h>
 
16
#include <set>
 
17
#include <bitset>
 
18
 
 
19
extern "C" {
 
20
#include <loudmouth/loudmouth.h>
 
21
}
 
22
 
 
23
#include "jabber_whiteboard/typedefs.h"
 
24
#include "jabber_whiteboard/defines.h"
 
25
#include "jabber_whiteboard/buddy-list-manager.h"
 
26
 
 
27
#include "gc-alloc.h"
 
28
 
 
29
struct SPDesktop;
 
30
struct SPDocument;
 
31
 
 
32
namespace Inkscape {
 
33
namespace XML {
 
34
class Node;
 
35
}
 
36
}
 
37
 
 
38
namespace Inkscape {
 
39
 
 
40
namespace Whiteboard {
 
41
 
 
42
class ReceiveMessageQueue;
 
43
class SendMessageQueue;
 
44
class XMLNodeTracker;
 
45
class SessionManager;
 
46
class MessageHandler;
 
47
class ChatMessageHandler;
 
48
class Callbacks;
 
49
class SessionFile;
 
50
class SessionFilePlayer;
 
51
class UndoStackObserver;
 
52
class Serializer;
 
53
class Deserializer;
 
54
 
 
55
/// Jabber resource name
 
56
#define RESOURCE_NAME   "Inkboard"
 
57
 
 
58
/// connectToServer return values
 
59
#define CONNECT_SUCCESS         0
 
60
#define FAILED_TO_CONNECT       1
 
61
#define INVALID_AUTH            2
 
62
#define SSL_INITIALIZATION_ERROR        3
 
63
 
 
64
/// sendMessage return values
 
65
#define SEND_SUCCESS                    0
 
66
#define CONNECTION_ERROR                1
 
67
#define UNKNOWN_OUTGOING_TYPE   2
 
68
#define NO_RECIPIENT_JID                3
 
69
 
 
70
/**
 
71
 * Structure grouping data items pertinent to a whiteboard session.
 
72
 *
 
73
 * SessionData holds all session data for both 1:1 and chatroom conferences.
 
74
 * Access to members should be controlled by first querying the status bitset
 
75
 * to see if useful data will actually exist in that member -- i.e. checking
 
76
 * status[IN_CHATROOM] to see if the chatters set will contain anything.
 
77
 * It usually won't hurt to do a straight query -- there are very few members
 
78
 * that remain uninitialized for very long -- but it's a good idea to check.
 
79
 */
 
80
struct SessionData {
 
81
public:
 
82
        /**
 
83
         * Constructor.
 
84
         *
 
85
         * \param sm The SessionManager with which a SessionData instance should be
 
86
         * associated with.
 
87
         */
 
88
        SessionData(SessionManager *sm);
 
89
 
 
90
        ~SessionData();
 
91
 
 
92
        /**
 
93
         * The JID of the recipient: either another user JID or the JID of a chatroom.
 
94
         */
 
95
        gchar const* recipient;
 
96
 
 
97
        /**
 
98
         * Pointer to Loudmouth connection structure.
 
99
         * Used for Loudmouth calls that require it.
 
100
         */
 
101
        LmConnection* connection;
 
102
 
 
103
        /**
 
104
         * SSL information structure for SSL connections.
 
105
         */
 
106
        LmSSL* ssl;
 
107
 
 
108
        /**
 
109
         * Flag indicating whether or not we should ignore further SSL errors for a given session.
 
110
         */
 
111
        bool ignoreFurtherSSLErrors;
 
112
 
 
113
 
 
114
        /**
 
115
         * A user's handle in a Jabber chatroom.
 
116
         */
 
117
        Glib::ustring chat_handle;
 
118
 
 
119
        /**
 
120
         * Name of the chatroom that a user in a chatroom is connected to.
 
121
         */
 
122
        Glib::ustring chat_name;
 
123
 
 
124
        /**
 
125
         * Name of the conference server.
 
126
         */
 
127
        Glib::ustring chat_server;
 
128
 
 
129
        // Message queues
 
130
        
 
131
        /**
 
132
         * Map associating senders to receive queues.
 
133
         */
 
134
        RecipientToReceiveQueueMap receive_queues;
 
135
 
 
136
        /**
 
137
         * Map associating senders to commit events sent by those committers.
 
138
         */
 
139
        CommitsQueue recipients_committed_queue;
 
140
 
 
141
        /**
 
142
         * Pointer to queue for messages to be sent.
 
143
         */
 
144
        SendMessageQueue* send_queue;
 
145
 
 
146
        // Message sequence numbers
 
147
        
 
148
        /**
 
149
         * The sequence number of the latest message sent by this client in a given session.
 
150
         * Used for determining the sequence number of the next message.
 
151
         */
 
152
        unsigned int sequence_number;
 
153
 
 
154
        //unsigned int latest_sent_transaction;
 
155
        //RecipientToLatestTransactionMap latest_processed_transactions;
 
156
 
 
157
 
 
158
        // Status tracking
 
159
        /**
 
160
         * Session state and status flags.
 
161
         */
 
162
        std::bitset< NUM_FLAGS > status;
 
163
        
 
164
        /**
 
165
         * Jabber buddy list data.
 
166
         */
 
167
        BuddyListManager buddyList;
 
168
 
 
169
        /**
 
170
         * List of participants in a Jabber chatroom.
 
171
         */
 
172
        ChatterList chatters;
 
173
 
 
174
        /**
 
175
         * Session file filename; blank if no session file is to be
 
176
         * recorded.
 
177
         */
 
178
        Glib::ustring sessionFile;
 
179
 
 
180
private:
 
181
        // access to containing class
 
182
        SessionManager *_sm;
 
183
 
 
184
        // noncopyable, nonassignable
 
185
        SessionData(SessionData const&);
 
186
        SessionData& operator=(SessionData const&);
 
187
};
 
188
 
 
189
 
 
190
// TODO: This class is huge.  It might be best to refactor it into smaller,
 
191
// more coherent chunks.
 
192
//
 
193
// TODO: convert to pass-by-reference where appropriate.  In particular, a lot of the
 
194
// string buffers passed to methods in the argument list can be made into references
 
195
// appropriately and easily.
 
196
 
 
197
/**
 
198
 * Session management class for Inkboard.
 
199
 *
 
200
 * By "session management", we refer to the management of all events that an Inkboard
 
201
 * session may need to handle: negotiating a connection to a Jabber server, negotiating
 
202
 * sessions with users and chatrooms, sending, receiving, and parsing messages, and so
 
203
 * forth.
 
204
 *
 
205
 * SessionManager instances are associated with Inkscape desktop objects on a 1:1 basis.
 
206
 */
 
207
class SessionManager {
 
208
public:
 
209
        /**
 
210
         * Constructor.
 
211
         *
 
212
         * \param desktop The desktop with which this SessionManager is associated.  */
 
213
        SessionManager(::SPDesktop *desktop);
 
214
        ~SessionManager();
 
215
 
 
216
        // Session tracking data
 
217
        
 
218
        /** 
 
219
         * Pointer to SessionData structure.
 
220
         */
 
221
        struct SessionData *session_data;
 
222
 
 
223
        // Inkscape interface
 
224
        
 
225
        /**
 
226
         * Set the desktop with which this SessionManager is associated.
 
227
         *
 
228
         * @param desktop the desktop with which this SessionManager should be associated
 
229
         */
 
230
        void setDesktop(::SPDesktop* desktop);
 
231
        
 
232
        // Session management
 
233
        
 
234
        /**
 
235
         * Connect to a Jabber server.
 
236
         *
 
237
         * @param server Jabber server URL
 
238
         * @param username Jabber username
 
239
         * @param pw password for Jabber account
 
240
         * @param usessl use SSL for connection
 
241
         *
 
242
         * @return CONNECT_SUCCESS if connection successful; FAILED_TO_CONNECT if connection failed or INVALID_AUTH
 
243
         * if authentication invalid
 
244
         */
 
245
        int connectToServer(Glib::ustring const& server, Glib::ustring const& port, Glib::ustring const& username, Glib::ustring const& pw, bool usessl);
 
246
 
 
247
        /**
 
248
         * Handle an SSL error by prompting the user for feedback, and continuing or aborting the connection
 
249
         * process based on that feedback.
 
250
         *
 
251
         * @param ssl pointer to LmSSL structure
 
252
         * @param status The error message
 
253
         *
 
254
         * @return LM_SSL_RESPONSE_CONTINUE if user wishes to continue establishing the connection or LM_SSL_RESPONSE_STOP if user wishes to abort connection
 
255
         */
 
256
        LmSSLResponse handleSSLError(LmSSL* ssl, LmSSLStatus status);
 
257
 
 
258
        /**
 
259
         * Disconnect from a Jabber server.  
 
260
         *
 
261
         * This invokes disconnectFromDocument().
 
262
         *
 
263
         * \see Inkscape::Whiteboard::SessionManager::disconnectFromDocument
 
264
         */
 
265
        void disconnectFromServer();
 
266
 
 
267
        /**
 
268
         * Disconnect from a document session.  The connection to the Jabber server is not 
 
269
         * broken, and may be reused to connect to a new document session.
 
270
         *
 
271
         */
 
272
        void disconnectFromDocument();
 
273
 
 
274
        /**
 
275
         * Perform session teardown.  This method by itself does not disconnect from a document or 
 
276
         * a Jabber server.
 
277
         *
 
278
         */
 
279
        void closeSession();
 
280
 
 
281
        /**
 
282
         * Set the recipient for Inkboard messages.
 
283
         *
 
284
         * @param recipientJID the recipient's JID
 
285
         */
 
286
        void setRecipient(char const* recipientJID);
 
287
 
 
288
        // Message sending utilities
 
289
        
 
290
        /**
 
291
         * Put an Inkboard message into the send queue.
 
292
         * This method does not actually send anything to an Inkboard client.
 
293
         *
 
294
         * \see Inkscape::Whiteboard::SessionManager::sendMessage
 
295
         *
 
296
         *
 
297
         * @param msg the message to send
 
298
         * @param type the type of message (only CHANGE_* types permitted)
 
299
         * @param chatroom whether or not this message is destined for a chatroom
 
300
         */
 
301
        void sendChange(Glib::ustring const& msg, MessageType type, std::string const& recipientJID, bool chatroom);
 
302
 
 
303
        /**
 
304
         * Send a message to an Inkboard client.
 
305
         *
 
306
         *
 
307
         * @param msgtype the type of message to send
 
308
         * @param sequence message sequence number
 
309
         * @param msg the message to send
 
310
         * @param recipientJID the JID of the recipient
 
311
         * @param chatroom whether or not this message is destined for a chatroom
 
312
         *
 
313
         * @return SEND_SUCCESS if successful; otherwise: UNKNOWN_OUTGOING_TYPE if msgtype is not recognized, NO_RECIPIENT_JID if recipientJID is NULL or blank, CONNECTION_ERROR if Jabber connection error occurred
 
314
         */
 
315
        int sendMessage(MessageType msgtype, unsigned int sequence, Glib::ustring const& msg, char const* recipientJID, bool chatroom);
 
316
 
 
317
        /**
 
318
         * Inform the user of a connection error via a Gtk::MessageDialog.
 
319
         *
 
320
         * @param errmsg message to display
 
321
         */
 
322
        void connectionError(Glib::ustring const& errmsg);
 
323
 
 
324
        /**
 
325
         * Stream the contents of the document with which this SessionManager is associated with to the given recipient.
 
326
         * 
 
327
         * @param recipientJID the JID of the recipient
 
328
         * @param newidsbuf buffer to store IDs of new nodes 
 
329
         * @param newnodesbuf buffer to store address of new nodes 
 
330
         */
 
331
        void resendDocument(char const* recipientJID, KeyToNodeMap& newidsbuf, NodeToKeyMap& newnodesbuf);
 
332
        
 
333
        
 
334
        /**
 
335
         * Send a connection request to another Inkboard client.
 
336
         *
 
337
         *
 
338
         * @param recipientJID the JID to connect to
 
339
         * @param document document message to send
 
340
         */
 
341
        void sendRequestToUser(std::string const& recipientJID);
 
342
 
 
343
        /**
 
344
         * Send a connection request to chatroom.
 
345
         * 
 
346
         * @param server server to connect to
 
347
         * @param chatroom name of chatroom
 
348
         * @param handle chatroom handle to use
 
349
         * @param password chatroom password; leave NULL if no password
 
350
         */
 
351
        void sendRequestToChatroom(Glib::ustring const& server, Glib::ustring const& chatroom, Glib::ustring const& handle, Glib::ustring const& password);
 
352
 
 
353
        /**
 
354
         * Send a connection request response to a user who requested to connect to us.
 
355
         *
 
356
         * @param requesterJID the JID of the user whom sent us the request
 
357
         * @param accepted_request whether or not we accepted the request
 
358
         */
 
359
        void sendConnectRequestResponse(char const* requesterJID, gboolean accepted_request); 
 
360
 
 
361
        /**
 
362
         * Method called when a connection request is received.  This method produces a dialog
 
363
         * that asks the user whether or not s/he would like to accept the request.
 
364
         *
 
365
         *
 
366
         * @param requesterJID the JID of the user whom sent us the request
 
367
         * @param msg the message associated with this request
 
368
         */
 
369
        void receiveConnectRequest(gchar const* requesterJID);
 
370
 
 
371
        /**
 
372
         * Method called when a response to a connection request is received.
 
373
         * This method performs any necessary session setup/teardown and user notification
 
374
         * depending on the response received.
 
375
         *
 
376
         *
 
377
         * @param msg the message associated with this request
 
378
         * @param response the response code
 
379
         * @param sender the JID of the user whom responded to our request
 
380
         */
 
381
        void receiveConnectRequestResponse(InvitationResponses response, std::string& sender);
 
382
 
 
383
        /**
 
384
         * Method called when a document synchronization request is received from a new conference
 
385
         * member in a chatroom.
 
386
         *
 
387
         * \param recipient the recipient JID
 
388
         */
 
389
        void receiveConnectRequestResponseChat(gchar const* recipient);
 
390
 
 
391
        // Message parsing and passing
 
392
        
 
393
        /**
 
394
         * Processes a group of document change messages.
 
395
         *
 
396
         * \param changemsg The change message group to process.
 
397
         */
 
398
        void receiveChange(Glib::ustring const& changemsg);
 
399
 
 
400
        // Logging and session file handling
 
401
        /**
 
402
         * Start a session log with the given filename.
 
403
         *
 
404
         * \param filename Full path to the file that the session log should be written to.
 
405
         * \throw Glib::FileError Thrown if an exception is thrown during session file creation.
 
406
         */
 
407
        void startLog(Glib::ustring filename);
 
408
 
 
409
        /**
 
410
         * Load a session file for playback.
 
411
         *
 
412
         * \param filename Full path to the session file that is to be loaded.
 
413
         */
 
414
        void loadSessionFile(Glib::ustring filename);
 
415
 
 
416
        /**
 
417
         * Returns whether or not the session is in session file playback mode.
 
418
         *
 
419
         * \return Whether or not the session is in session file playback mode.
 
420
         */
 
421
        bool isPlayingSessionFile();
 
422
 
 
423
        // User event notification
 
424
        
 
425
        /**
 
426
         * Method to notify the user that a whiteboard session to another user has been successfully
 
427
         * established.
 
428
         *
 
429
         * \param JID The JID with whom the user established a session.
 
430
         */
 
431
        void userConnectedToWhiteboard(gchar const* JID);
 
432
 
 
433
        /**
 
434
         * Method to notify the user that the other user in a user-to-user whiteboard session
 
435
         * has disconnected.
 
436
         *
 
437
         * \param JID The JID of the user who left the whiteboard session.
 
438
         */
 
439
        void userDisconnectedFromWhiteboard(std::string const& JID);
 
440
 
 
441
        // Queue dispatching and UI setup
 
442
        
 
443
        /**
 
444
         * Start the send queue for this session.
 
445
         */
 
446
        void startSendQueueDispatch();
 
447
 
 
448
        /**
 
449
         * Stop the send queue for this session.
 
450
         */
 
451
        void stopSendQueueDispatch();
 
452
 
 
453
        /**
 
454
         * Start the receive queue for this session.
 
455
         */
 
456
        void startReceiveQueueDispatch();
 
457
 
 
458
        /**
 
459
         * Stop the receive queue for this session.
 
460
         */
 
461
        void stopReceiveQueueDispatch();
 
462
 
 
463
        /**
 
464
         * Clear all layers, definitions, and metadata from the document with which a
 
465
         * SessionManager instance is associated. 
 
466
         *
 
467
         * Documents are cleared to assist synchronization between two clients
 
468
         * or a client and a chatroom.
 
469
         */
 
470
        void clearDocument();
 
471
 
 
472
        /**
 
473
         * Set up objects for handling actions generated by the user interacting with
 
474
         * Inkscape.  This includes marking the active session as being in a whiteboard session,
 
475
         * starting send and receive queues, and creating an event serializer and deserializer.
 
476
         *
 
477
         * \see Inkscape::Whiteboard::SendMessageQueue
 
478
         * \see Inkscape::Whiteboard::ReceiveMessageQueue
 
479
         * \see Inkscape::Whiteboard::Serializer
 
480
         * \see Inkscape::Whiteboard::Deserializer
 
481
         */
 
482
        void setupInkscapeInterface();
 
483
 
 
484
        /**
 
485
         * Reset whiteboard verbs to INITIAL state.
 
486
         */
 
487
        void setInitialVerbSensitivity() {
 
488
                this->_setVerbSensitivity(INITIAL);
 
489
        }
 
490
 
 
491
        /**
 
492
         * Set up the event commit listener.
 
493
         *
 
494
         * The event commit listener watches for events that are committed to the document's undo log,
 
495
         * serializes those events, and then adds them to the message send queue.
 
496
         *
 
497
         * \see Inkscape::Whiteboard::SendMessageQueue
 
498
         * \see Inkscape::Whiteboard::UndoStackObserver
 
499
         */
 
500
        void setupCommitListener();
 
501
 
 
502
        // Private object retrieval
 
503
        ::SPDesktop* desktop();
 
504
        ::SPDocument* document();
 
505
        Callbacks* callbacks();
 
506
        Whiteboard::UndoStackObserver* undo_stack_observer();
 
507
        Serializer* serializer();
 
508
        XMLNodeTracker* node_tracker();
 
509
        Deserializer* deserializer();
 
510
        ChatMessageHandler* chat_handler();
 
511
        SessionFilePlayer* session_player();
 
512
        SessionFile* session_file();
 
513
 
 
514
private:
 
515
        // Internal logging methods
 
516
        void _log(Glib::ustring const& message);
 
517
        void _commitLog();
 
518
        void _closeLog();
 
519
        void _tryToStartLog();
 
520
 
 
521
        enum SensitivityMode {
 
522
                        INITIAL,
 
523
                        ESTABLISHED_CONNECTION,
 
524
                        ESTABLISHED_SESSION,
 
525
                        DISCONNECTED_FROM_SESSION
 
526
        };
 
527
 
 
528
        void _setVerbSensitivity(SensitivityMode mode);
 
529
 
 
530
        bool _pollReceiveConnectRequest(Glib::ustring const recipient);
 
531
 
 
532
        ::SPDesktop* _myDesktop;
 
533
        ::SPDocument* _myDoc;
 
534
        Whiteboard::UndoStackObserver* _myUndoObserver;
 
535
        XMLNodeTracker* _myTracker;
 
536
        ChatMessageHandler* _myChatHandler;
 
537
        Callbacks* _myCallbacks;
 
538
        SessionFile* _mySessionFile;
 
539
        SessionFilePlayer* _mySessionPlayer;
 
540
        MessageHandler* _myMessageHandler;
 
541
        Serializer* _mySerializer;
 
542
        Deserializer* _myDeserializer; 
 
543
 
 
544
        sigc::connection _send_queue_dispatcher;
 
545
        sigc::connection _receive_queue_dispatcher;
 
546
        sigc::connection _notify_incoming_request;
 
547
 
 
548
        // noncopyable, nonassignable
 
549
        SessionManager(SessionManager const&);
 
550
        SessionManager& operator=(SessionManager const&);
 
551
};
 
552
 
 
553
}
 
554
 
 
555
}
 
556
 
 
557
#endif
 
558
 
 
559
/*
 
560
  Local Variables:
 
561
  mode:c++
 
562
  c-file-style:"stroustrup"
 
563
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
564
  indent-tabs-mode:nil
 
565
  fill-column:99
 
566
  End:
 
567
*/
 
568
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :