Merge branch 'master' of https://git.maemo.org/projects/qtmeetings
[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::cancelFetchMeetingDetails()
95 {
96         const RequestData *rd = findRequest( GetCalendarItem );
97         if( rd != NULL ) {
98                 int id = rd->requestId;
99                 iCancelledRequests.append( id );
100         }
101 }
102
103 void CommunicationManager::getMeetingDetails( Meeting &aMeeting )
104 {
105         ReqMsgGetCalendarItem msg( aMeeting.secondaryId() );
106         
107         QByteArray arr = msg.getMessage();
108         
109         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), arr );
110         qDebug() << "CommunicationManager::getMeetingDetails: id: " << id;
111         if( id )
112         {
113                 addRequest( GetCalendarItem, id );
114                 iRequestInfos.first()->meeting = &aMeeting;
115         }
116 }
117
118 void CommunicationManager::requestFinished( int aRequestId, int aError )
119 {
120         RequestData* rd = takeRequest( aRequestId );
121         if( iCancelledRequests.contains( rd->requestId ) )
122         {
123                 iCancelledRequests.removeAll( rd->requestId );
124                 delete rd;
125                 return;
126         }
127         QByteArray* response = iFetchingCommunication->response( aRequestId );
128         qDebug() << "CommunicationManager::requestFinished: id: " << aRequestId << " error: " << aError;
129
130         if( aError != (int)(QHttp::NoError) || rd == NULL || response == NULL )
131         {
132                 int err = aError;
133                 if( rd == NULL || response == NULL )
134                         err = 10;
135                 delete rd;
136                 emit error( ERROR_BASE+(int)err, CommunicationManager::FetchingCommunication );
137                 return;
138         }
139
140         switch( rd->type )
141         {
142         case GetUserAvailability:
143                 {
144                 ResMsgGetUserAvailability msg( *response );
145         
146                 while ( !iMeetings.isEmpty() )
147                         delete iMeetings.takeFirst();
148         
149                 int err = msg.getMeetingsFromResponse( iMeetings, *(rd->room) );
150                 if( err )
151                         emit error( ERROR_BASE+8, CommunicationManager::FetchingCommunication );
152                 else
153                         emit meetingsFetched( iMeetings );
154                 break;
155                 }
156         case ConvertId:
157                 {
158                 ResponseMessage msg( *response );
159                 QString id = msg.getNodeValue( QString( "Id" ),
160                                                                            QDomNode::AttributeNode,
161                                                                            QString( "AlternateId" ) );
162                 qDebug( "ID IS: %s", id.toStdString().data() );
163                 rd->meeting->setSecondaryId( id );
164                 getMeetingDetails( *(rd->meeting) );
165                 break;
166                 }
167         case GetCalendarItem:
168                 {
169                 ResMsgGetCalendarItem msg( *response );
170                 int err = msg.getMeetingDetailsFromResponse( *(rd->meeting) );
171                 if( err )
172                         emit error( ERROR_BASE+9, CommunicationManager::FetchingCommunication );
173                 else
174                         emit meetingDetailsFetched( *(rd->meeting) );
175                 break;
176                 }
177         }
178         delete response;
179         delete rd;
180 }
181
182 void CommunicationManager::readProgress( int /*aRequestId*/, int aDone, int aTotal )
183 {
184         emit readProgress( aDone, aTotal, CommunicationManager::FetchingCommunication );
185 }
186
187 void CommunicationManager::addRequest( RequestType aType, int aRequestId )
188 {
189         RequestData* rd = new RequestData( aType, aRequestId );
190         iRequestInfos.append( rd );
191 }
192
193 CommunicationManager::RequestData* CommunicationManager::takeRequest( int aRequestId )
194 {
195         if( aRequestId == 0 )
196                 return NULL;
197
198         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
199         {
200                 struct RequestData* rd = iRequestInfos[i];
201                 if( rd->requestId == aRequestId )
202                 {
203                         iRequestInfos.removeAt( i );
204                         return rd;
205                 }
206         }
207         return NULL;
208 }
209
210 const CommunicationManager::RequestData* CommunicationManager::findRequest( RequestType aRequestType ) const
211 {
212         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
213         {
214                 struct RequestData* rd = iRequestInfos[i];
215                 if( rd->type == aRequestType )
216                 {
217                         return rd;
218                 }
219         }
220         return NULL;
221 }