Multiple simultaneous request support to Communication
[qtmeetings] / src / IO / Communication / CommunicationManager.cpp
1 #include "CommunicationManager.h"
2 #include "Communication.h"
3 #include "ConnectionSettings.h"
4 #include "Meeting.h"
5 #include "Room.h"
6 #include <QDateTime>
7 #include <QDomDocument>
8 #include <QDebug>
9
10 static const int ERROR_BASE=100;
11
12 CommunicationManager::CommunicationManager( const ConnectionSettings &aConnection )
13 {
14         iConnectionSettings = new ConnectionSettings( aConnection );
15         iModifyingCommunication = NULL;
16         iFetchingCommunication = new Communication( aConnection );
17
18         if ( iFetchingCommunication )
19         {
20                 connect( iFetchingCommunication,
21                                  SIGNAL( readProgress( int, int, int ) ),
22                                  this,
23                                  SLOT( readProgress( int, int, int ) )
24                                 );
25                 connect( iFetchingCommunication,
26                                  SIGNAL( requestFinished( int, int ) ),
27                                  this,
28                                  SLOT( requestFinished( int, int ) )
29                                 );
30         }
31 }
32
33 CommunicationManager::~CommunicationManager()
34 {
35         delete iConnectionSettings;
36         delete iModifyingCommunication;
37         delete iFetchingCommunication;
38         while ( !iMeetings.isEmpty() )
39                 delete iMeetings.takeFirst();
40 }
41
42 void CommunicationManager::fetchMeetings( const QDateTime &aFrom, const QDateTime &aUntil, const Room &aIn )
43 {
44         //prevent making multiple simultaneous user availibility requests
45         const RequestData* rd = findRequest( GetUserAvailability );
46         if( rd )
47                 return;
48         ReqMsgGetUserAvailability msg;
49         msg.setTimeZone();
50         msg.setTimeWindow( aFrom, aUntil );
51         msg.addUser( aIn.address() );
52                 
53         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), msg.getMessage() );
54         qDebug() << "CommunicationManager::fetchMeetings: id: " << id;
55         if( id )
56         {
57                 addRequest( GetUserAvailability, id );
58                 iRequestInfos.first()->room = new Room( aIn );
59         }
60 }
61
62 void CommunicationManager::getSecondaryIdForMeeting( Meeting &aMeeting )
63 {
64         ReqMsgConvertMeetingId msg( aMeeting.primaryId(), aMeeting.room().address() );
65         
66         QByteArray arr = msg.getMessage();
67
68         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), arr );
69         qDebug() << "CommunicationManager::getSecondaryIdForMeeting: id: " << id;
70         if( id )
71         {
72                 addRequest( ConvertId, id );
73                 iRequestInfos.first()->meeting = &aMeeting;
74         }
75 }
76
77 void CommunicationManager::fetchMeetingDetails( Meeting& aMeeting )
78 {
79         if( aMeeting.detailsAvailable() )
80         {
81                 emit meetingDetailsFetched( aMeeting );
82                 return;
83         }
84         if( aMeeting.secondaryId().isEmpty() )
85         {
86                 getSecondaryIdForMeeting( aMeeting );
87         }
88         else
89         {
90                 getMeetingDetails( aMeeting );
91         }
92 }
93
94 void CommunicationManager::getMeetingDetails( Meeting &aMeeting )
95 {
96         ReqMsgGetCalendarItem msg( aMeeting.secondaryId() );
97         
98         QByteArray arr = msg.getMessage();
99         
100         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), arr );
101         qDebug() << "CommunicationManager::getMeetingDetails: id: " << id;
102         if( id )
103         {
104                 addRequest( GetCalendarItem, id );
105                 iRequestInfos.first()->meeting = &aMeeting;
106         }
107 }
108
109 void CommunicationManager::requestFinished( int aRequestId, int aError )
110 {
111         RequestData* rd = takeRequest( aRequestId );
112         QByteArray* response = iFetchingCommunication->response( aRequestId );
113         qDebug() << "CommunicationManager::requestFinished: id: " << aRequestId << " error: " << aError;
114
115         if( aError != (int)(QHttp::NoError) || rd == NULL || response == NULL )
116         {
117                 int err = aError;
118                 if( rd == NULL || response == NULL )
119                         err = 10;
120                 delete rd;
121                 emit error( ERROR_BASE+(int)err, CommunicationManager::FetchingCommunication );
122                 return;
123         }
124
125         switch( rd->type )
126         {
127         case GetUserAvailability:
128                 {
129                 ResMsgGetUserAvailability msg( *response );
130         
131                 while ( !iMeetings.isEmpty() )
132                         delete iMeetings.takeFirst();
133         
134                 int err = msg.getMeetingsFromResponse( iMeetings, *(rd->room) );
135                 if( err )
136                         emit error( ERROR_BASE+8, CommunicationManager::FetchingCommunication );
137                 else
138                         emit meetingsFetched( iMeetings );
139                 break;
140                 }
141         case ConvertId:
142                 {
143                 ResponseMessage msg( *response );
144                 QString id = msg.getNodeValue( QString( "Id" ),
145                                                                            QDomNode::AttributeNode,
146                                                                            QString( "AlternateId" ) );
147                 qDebug( "ID IS: %s", id.toStdString().data() );
148                 rd->meeting->setSecondaryId( id );
149                 getMeetingDetails( *(rd->meeting) );
150                 break;
151                 }
152         case GetCalendarItem:
153                 {
154                 ResMsgGetCalendarItem msg( *response );
155                 int err = msg.getMeetingDetailsFromResponse( *(rd->meeting) );
156                 if( err )
157                         emit error( ERROR_BASE+9, CommunicationManager::FetchingCommunication );
158                 else
159                         emit meetingDetailsFetched( *(rd->meeting) );
160                 break;
161                 }
162         }
163         delete response;
164         delete rd;
165 }
166
167 void CommunicationManager::readProgress( int /*aRequestId*/, int aDone, int aTotal )
168 {
169         emit readProgress( aDone, aTotal, CommunicationManager::FetchingCommunication );
170 }
171
172 void CommunicationManager::addRequest( RequestType aType, int aRequestId )
173 {
174         RequestData* rd = new RequestData( aType, aRequestId );
175         iRequestInfos.append( rd );
176 }
177
178 CommunicationManager::RequestData* CommunicationManager::takeRequest( int aRequestId )
179 {
180         if( aRequestId == 0 )
181                 return NULL;
182
183         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
184         {
185                 struct RequestData* rd = iRequestInfos[i];
186                 if( rd->requestId == aRequestId )
187                 {
188                         iRequestInfos.removeAt( i );
189                         return rd;
190                 }
191         }
192         return NULL;
193 }
194
195 const CommunicationManager::RequestData* CommunicationManager::findRequest( RequestType aRequestType ) const
196 {
197         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
198         {
199                 struct RequestData* rd = iRequestInfos[i];
200                 if( rd->type == aRequestType )
201                 {
202                         return rd;
203                 }
204         }
205         return NULL;
206 }