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