2f340a076ad7b936be14a62149c2ce6f228ea25a
[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 int aWeek, const int aYear, const Room &aIn )
43 {
44         //prevent making multiple simultaneous user availibility requests
45         //TODO: Would be nice to queue these requests instead of just aborting 
46         const RequestData* rd = findRequest( GetUserAvailability );
47         if( rd )
48                 return;
49         
50         // Set from to beginning, 00:00 of the requested week
51         QDateTime from = QDateTime::currentDateTime();
52         from = from.addYears( aYear - from.date().year() );
53         from = from.addDays( -1*(from.date().dayOfWeek()-1) );
54         from = from.addDays( (aWeek - from.date().weekNumber())*7 );
55         QTime midnight = from.time();
56         midnight.setHMS( 0,0,0 );
57         from.setTime( midnight );
58         qDebug() << "CommunicationManager::fetchMeetings from: " << from.toString();
59         
60         QDateTime until = from.addDays(7);
61         qDebug() << "CommunicationManager::fetchMeetings until: " << until.toString();
62         
63         
64         ReqMsgGetUserAvailability msg;
65         msg.setTimeZone();
66         msg.setTimeWindow( from, until );
67         msg.addUser( aIn.address() );
68                 
69         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), msg.getMessage() );
70         qDebug() << "CommunicationManager::fetchMeetings: id: " << id;
71         if( id )
72         {
73                 addRequest( GetUserAvailability, id );
74                 iRequestInfos.first()->room = new Room( aIn );
75         }
76 }
77
78 void CommunicationManager::getSecondaryIdForMeeting( Meeting &aMeeting )
79 {
80         ReqMsgConvertMeetingId msg( aMeeting.primaryId(), aMeeting.room().address() );
81         
82         QByteArray arr = msg.getMessage();
83
84         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), arr );
85         qDebug() << "CommunicationManager::getSecondaryIdForMeeting: id: " << id;
86         if( id )
87         {
88                 addRequest( ConvertId, id );
89                 iRequestInfos.first()->meeting = &aMeeting;
90         }
91 }
92
93 void CommunicationManager::fetchMeetingDetails( Meeting& aMeeting )
94 {
95         if( aMeeting.detailsAvailable() )
96         {
97                 emit meetingDetailsFetched( aMeeting );
98                 return;
99         }
100         if( aMeeting.secondaryId().isEmpty() )
101         {
102                 getSecondaryIdForMeeting( aMeeting );
103         }
104         else
105         {
106                 getMeetingDetails( aMeeting );
107         }
108 }
109
110 void CommunicationManager::cancelFetchMeetingDetails()
111 {
112         const RequestData *rd = findRequest( GetCalendarItem );
113         if( rd != NULL ) {
114                 int id = rd->requestId;
115                 iCancelledRequests.append( id );
116         }
117 }
118
119 void CommunicationManager::getMeetingDetails( Meeting &aMeeting )
120 {
121         ReqMsgGetCalendarItem msg( aMeeting.secondaryId() );
122         
123         QByteArray arr = msg.getMessage();
124         
125         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), arr );
126         qDebug() << "CommunicationManager::getMeetingDetails: id: " << id;
127         if( id )
128         {
129                 addRequest( GetCalendarItem, id );
130                 iRequestInfos.first()->meeting = &aMeeting;
131         }
132 }
133
134 void CommunicationManager::requestFinished( int aRequestId, int aError )
135 {
136         RequestData* rd = takeRequest( aRequestId );
137         if( iCancelledRequests.contains( rd->requestId ) )
138         {
139                 iCancelledRequests.removeAll( rd->requestId );
140                 delete rd;
141                 return;
142         }
143         QByteArray* response = iFetchingCommunication->response( aRequestId );
144         qDebug() << "CommunicationManager::requestFinished: id: " << aRequestId << " error: " << aError;
145
146         if( aError != (int)(QHttp::NoError) || rd == NULL || response == NULL )
147         {
148                 int err = aError;
149                 if( rd == NULL || response == NULL )
150                         err = 10;
151                 delete rd;
152                 emit error( ERROR_BASE+(int)err, CommunicationManager::FetchingCommunication );
153                 return;
154         }
155
156         switch( rd->type )
157         {
158         case GetUserAvailability:
159                 {
160                 ResMsgGetUserAvailability msg( *response );
161         
162                 while ( !iMeetings.isEmpty() )
163                         delete iMeetings.takeFirst();
164         
165                 int err = msg.getMeetingsFromResponse( iMeetings, *(rd->room) );
166                 if( err )
167                         emit error( ERROR_BASE+8, CommunicationManager::FetchingCommunication );
168                 else
169                         emit meetingsFetched( iMeetings );
170                 break;
171                 }
172         case ConvertId:
173                 {
174                 ResponseMessage msg( *response );
175                 QString id = msg.getNodeValue( QString( "Id" ),
176                                                                            QDomNode::AttributeNode,
177                                                                            QString( "AlternateId" ) );
178                 qDebug( "ID IS: %s", id.toStdString().data() );
179                 rd->meeting->setSecondaryId( id );
180                 getMeetingDetails( *(rd->meeting) );
181                 break;
182                 }
183         case GetCalendarItem:
184                 {
185                 ResMsgGetCalendarItem msg( *response );
186                 int err = msg.getMeetingDetailsFromResponse( *(rd->meeting) );
187                 if( err )
188                         emit error( ERROR_BASE+9, CommunicationManager::FetchingCommunication );
189                 else
190                         emit meetingDetailsFetched( *(rd->meeting) );
191                 break;
192                 }
193         }
194         delete response;
195         delete rd;
196 }
197
198 void CommunicationManager::readProgress( int /*aRequestId*/, int aDone, int aTotal )
199 {
200         emit readProgress( aDone, aTotal, CommunicationManager::FetchingCommunication );
201 }
202
203 void CommunicationManager::addRequest( RequestType aType, int aRequestId )
204 {
205         RequestData* rd = new RequestData( aType, aRequestId );
206         iRequestInfos.append( rd );
207 }
208
209 CommunicationManager::RequestData* CommunicationManager::takeRequest( int aRequestId )
210 {
211         if( aRequestId == 0 )
212                 return NULL;
213
214         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
215         {
216                 struct RequestData* rd = iRequestInfos[i];
217                 if( rd->requestId == aRequestId )
218                 {
219                         iRequestInfos.removeAt( i );
220                         return rd;
221                 }
222         }
223         return NULL;
224 }
225
226 const CommunicationManager::RequestData* CommunicationManager::findRequest( RequestType aRequestType ) const
227 {
228         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
229         {
230                 struct RequestData* rd = iRequestInfos[i];
231                 if( rd->type == aRequestType )
232                 {
233                         return rd;
234                 }
235         }
236         return NULL;
237 }