f3db49091f4b6145f1086ccbe4038c2c3a8c7058
[qtmeetings] / src / IO / Communication / MessagingUtils.cpp
1 #include <QUrl>
2 #include <time.h>
3
4 #include "MessagingUtils.h"
5 #include "Meeting.h"
6 #include "Configuration.h"
7
8 /*
9  * BaseMessage class functions
10 */
11 BaseMessage::BaseMessage()
12 {
13 #ifdef MU_DEBUG
14         qDebug( "BaseMessage::BaseMessage" );
15 #endif
16         iMessage = new QDomDocument();
17 #ifdef MU_DEBUG
18         qDebug( "BaseMessage::BaseMessage end" );
19 #endif
20 }
21
22 BaseMessage::~BaseMessage()
23 {
24 #ifdef MU_DEBUG
25         qDebug( "BaseMessage::~BaseMessage" );
26 #endif
27         if( iMessage )
28                 {
29                 delete iMessage;
30                 iMessage = 0;
31                 }
32 #ifdef MU_DEBUG
33         qDebug( "BaseMessage::~BaseMessage end" );
34 #endif
35 }
36
37 QList<QDomNode> BaseMessage::getNodesByName( const QString& aNodeName, const QString& aParentName, QDomNode* aRootNode )
38 {
39 #ifdef MU_DEBUG
40         qDebug( "BaseMessage::getNodesByName" );
41 #endif
42         
43         //TODO: Add implementation for attribute search
44         
45         QDomNodeList list;
46         QList<QDomNode> specList;
47         
48         list = ( aRootNode ) ? aRootNode->toElement().elementsByTagName( aNodeName ) : iMessage->elementsByTagName( aNodeName );
49
50         for( int i=0; i<list.count(); i++ )
51         {
52                 if( aParentName != QString::null )
53                 {
54                 if( !list.item( i ).parentNode().isNull() && list.item( i ).parentNode().isElement() && list.item( i ).parentNode().toElement().tagName().compare( aParentName ) == 0 )
55                         specList.append( list.item( i ) );
56                 }
57                 else
58                         specList.append( list.item( i ) );
59         }
60 #ifdef MU_DEBUG
61         qDebug( "BaseMessage::getNodesByName end" );
62 #endif          
63         return specList;
64 }
65
66 QDomNode BaseMessage::getNodeFromDocument( const QString& aNodeName,
67                                                                 QDomNode::NodeType aNodeType,
68                                                                 const QString& aParentName,
69                                                                 int aIndex,
70                                                                 QDomNode* aRootNode )
71 {
72 #ifdef MU_DEBUG
73         qDebug( "BaseMessage::getNodeFromDocument" );
74 #endif
75         QDomNode node;
76         if( aNodeType == QDomNode::ElementNode )
77                 node = getElementFromDocument( aNodeName, aParentName, aIndex, aRootNode );
78         else if( aNodeType == QDomNode::AttributeNode )
79                 node = getAttributeFromDocument( aNodeName, aParentName, aIndex, aRootNode );
80 #ifdef MU_DEBUG
81         qDebug( "BaseMessage::getNodeFromDocument end" );
82 #endif
83         return node;
84 }
85
86 QDomNode BaseMessage::getAttributeFromDocument( const QString& aAttributeName,
87                                                                 const QString& aParentName,
88                                                                 int aIndex,
89                                                                 QDomNode* aRootNode )
90 {
91 #ifdef MU_DEBUG
92         qDebug( "BaseMessage::getAttributeFromDocument" );
93 #endif
94
95         QDomNode root;
96         QDomNode node;
97         QDomNode parent;
98         
99         root = ( !aRootNode ) ? iMessage->documentElement() : *aRootNode;
100         if( root.isNull() )
101                 {
102 #ifdef MU_DEBUG
103         qDebug( "BaseMessage::getAttributeFromDocument : RootNode is NULL." );
104 #endif          
105                 return node;
106                 }
107
108         if( aParentName != QString::null )
109         {
110                 if( root.isElement() )
111                 {
112                         QDomNodeList list = root.toElement().elementsByTagName( aParentName );
113                         if( list.count() > 0 ) parent = list.item( 0 );
114                 }
115         }
116         
117         QDomNamedNodeMap attrs = parent.attributes();
118         
119         int count = attrs.count();
120         if( count==0 || aIndex >= count || !attrs.contains( aAttributeName ) ) return root;
121
122         QList<QDomAttr> list;
123
124         for( int i=0; i<count; i++ )
125         {
126                 QDomAttr attr = attrs.item( i ).toAttr();
127
128                 if( attr.name().compare( aAttributeName ) == 0 || attr.localName().compare( aAttributeName ) == 0 )
129                 {
130                         if( aParentName != QString::null && ( attr.ownerElement().tagName().compare( aParentName ) == 0 || attr.ownerElement().localName().compare( aParentName ) == 0 ))
131                         {
132                                 list.append( attr );
133                         }
134                         else
135                                 list.append( attr );
136                 }
137
138         }
139
140         if( list.count() > 0 )
141                 node = list.at( aIndex );
142
143 #ifdef MU_DEBUG
144         qDebug( "BaseMessage::getAttributeFromDocument end." );
145 #endif  
146         
147         return node;
148 }
149
150 QDomNode BaseMessage::getElementFromDocument( const QString& aElementName,
151                                                                 const QString& aParentName,
152                                                                 int aIndex,
153                                                                 QDomNode* aRootNode )
154 {
155 #ifdef MU_DEBUG
156         qDebug( "BaseMessage::getElementFromDocument" );
157 #endif
158                 QDomNode node;
159                 QDomNodeList elems;
160
161                 if( !aRootNode )
162                 {
163                 elems = iMessage->elementsByTagName( aElementName );
164                 }
165                 else
166                 {
167                 elems = aRootNode->toElement().elementsByTagName( aElementName );
168                 }
169
170                 int count = elems.count();
171                 if( count == 0 || aIndex >= count )
172                 { 
173 #ifdef MU_DEBUG
174         qDebug( "BaseMessage::getElementFromDocument : No Elements found." );
175 #endif                  
176                         return node; //no elements found
177                 }
178
179                 QList<QDomElement> list;
180
181                 for( int i=0; i<count; i++ )
182                 {
183                         QDomElement elem = elems.item( i ).toElement();
184                         if( elem.tagName().compare( aElementName ) == 0 || elem.localName().compare( aElementName ) == 0 )
185                         {
186                                 if( aParentName != QString::null )
187                                 {
188                                         if( !elem.parentNode().isNull() )
189                                         {
190                                                 if( elem.parentNode().toElement().tagName().compare( aParentName ) == 0 || elem.parentNode().toElement().tagName().compare( aParentName ) == 0 )
191                                                         list.append( elem );
192                                         }
193                                 }
194                                 else
195                                         list.append( elem );
196                         }
197
198                 }
199
200                 if( list.count() > 0 )
201                         node = list.at( aIndex );
202
203 #ifdef MU_DEBUG
204         qDebug( "BaseMessage::getElementFromDocument end" );
205 #endif          
206                 return node;
207 }
208
209 bool BaseMessage::matchName( const QDomNode& aNode, const QString& aName )
210 {
211 #ifdef MU_DEBUG
212         qDebug( "BaseMessage::matchName" );
213 #endif
214         if( aNode.isElement() )
215         {
216                 if( aNode.toElement().tagName().toLower().compare( aName.toLower() ) == 0
217                                 || aNode.localName().toLower().compare( aName.toLower() ) == 0 )
218                 {
219 #ifdef MU_DEBUG
220         qDebug( "BaseMessage::matchName end" );
221 #endif                  
222                         return true;
223                 }
224         }
225         else if( aNode.isAttr() )
226         {
227                 if( aNode.toAttr().name().toLower().compare( aName.toLower() ) == 0
228                                 || aNode.localName().toLower().compare( aName.toLower() ) == 0 )
229                 {
230 #ifdef MU_DEBUG
231         qDebug( "BaseMessage::matchName end" );
232 #endif                  
233                         return true;
234                 }
235         }
236 #ifdef MU_DEBUG
237         qDebug( "BaseMessage::matchName : No match." );
238 #endif  
239         return false;
240 }
241
242 QByteArray BaseMessage::getMessage()
243 {
244 #ifdef MU_DEBUG
245         qDebug( "BaseMessage::getMessage" );
246 #endif
247         QByteArray msg;
248         if( iMessage )
249         {
250                 msg.append( iMessage->toByteArray() );
251         }
252 #ifdef MU_DEBUG
253         qDebug( "BaseMessage::getMessage end" );
254 #endif  
255         return msg;
256 }
257
258 /*
259  * RequestMessage class functions
260 */
261 RequestMessage::RequestMessage( RequestCommandId aCommandId ) : iCurrCmd( aCommandId )
262 {
263 #ifdef MU_DEBUG
264         qDebug( "RequestMessage::RequestMessage" );
265 #endif
266         createEnvelopeBase();
267
268         if( aCommandId != ReqCmdNoCommand )
269         {
270                 createMessageStructure( aCommandId );
271         }
272 #ifdef MU_DEBUG
273         qDebug( "RequestMessage::RequestMessage end" );
274 #endif
275 }
276
277 RequestMessage::RequestMessage( const QString& /*aFileName*/ )
278 {
279         //createEnvelopeBase();
280         //TODO: read operation structures from a file
281 }
282
283 int RequestMessage::addNode( const QDomNode& aNode, QDomNode::NodeType aNodeType, const QString& aParentName, int aIndex, QDomNode* aRootNode )
284 {
285 #ifdef MU_DEBUG
286         qDebug( "RequestMessage::addNode" );
287 #endif
288
289         if( !iMessage )
290         {
291 #ifdef MU_DEBUG
292         qDebug( "RequestMessage::addNode : iMessage is NULL." );
293 #endif  
294                 return MsgErrSomeError;
295         }
296
297         int err = MsgErrNoError;
298
299         if( aNodeType == QDomNode::ElementNode && aNode.isElement() )
300         {
301                 if( aParentName == QString::null )
302                 {
303                         if( !aRootNode )
304                         iMessage->appendChild( aNode );
305                         else
306                         aRootNode->appendChild( aNode );
307                 }
308                 else
309                 {
310                         QDomNodeList list = ( aRootNode ) ? aRootNode->toElement().elementsByTagName( aParentName ) : iMessage->elementsByTagName( aParentName );
311                                 
312                         if( list.count() == 0 || aIndex >= list.count() ) err = MsgErrSomeError;
313                         else
314                         {
315                                 QDomElement node = list.at( aIndex ).toElement();
316                                 node.appendChild( aNode );
317                         }
318                 }
319         }
320         else if( aNodeType == QDomNode::AttributeNode && aNode.isAttr() )
321         {
322                 if( aParentName != QString::null )
323                 {
324                         QDomNodeList list = ( aRootNode ) ? aRootNode->toElement().elementsByTagName( aParentName ) : iMessage->elementsByTagName( aParentName );
325                                 
326                         if( list.count() == 0 || aIndex >= list.count() ) err = MsgErrSomeError;
327                         else
328                         {
329                                 QDomElement node = list.at( aIndex ).toElement();
330                                 node.setAttributeNode( aNode.toAttr() );
331                         }
332                 }
333                 else
334                         err = MsgErrSomeError; //Attribute must have a parent specified
335         }
336         else
337                 err = MsgErrSomeError;
338
339 #ifdef MU_DEBUG
340         qDebug( "RequestMessage::addNode end : err=%d", err );
341 #endif          
342         return err;
343 }
344
345 int RequestMessage::setNodeValue( const QString& aNodeName, const QString& aValue, QDomNode::NodeType aNodeType, const QString& aParentName, int aIndex, QDomNode* aRootNode )
346 {
347 #ifdef MU_DEBUG
348         qDebug( "RequestMessage::setNodeValue" );
349 #endif
350
351         QDomNode node = getNodeFromDocument( aNodeName, aNodeType, aParentName, aIndex, aRootNode );
352         if( node.isNull() || !iMessage )
353                 {
354 #ifdef MU_DEBUG
355         qDebug( "RequestMessage::setNodeValue : Node is NULL or iMessage is NULL." );
356 #endif          
357                 return MsgErrSomeError;
358                 }
359
360         int err = MsgErrNoError;
361
362         if( node.isElement() )
363         {
364                 node.appendChild( iMessage->createTextNode( aValue ) );
365         }
366         else if( node.isAttr() )
367                 node.toAttr().setValue( aValue );
368         else
369                 err = MsgErrSomeError;
370
371 #ifdef MU_DEBUG
372         qDebug( "RequestMessage::setNodeValue end : err=%d", err );
373 #endif  
374         return err;
375 }
376
377 int RequestMessage::createEnvelopeBase()
378 {
379 #ifdef MU_DEBUG
380         qDebug( "RequestMessage::createEnvelopeBase" );
381 #endif
382         if( iMessage )
383                 {
384                 delete iMessage;
385                 iMessage = 0;
386                 }
387
388         iMessage = new QDomDocument();
389
390         int size = sizeof( reqCmdArrayEnvelopeBase ) / sizeof( MessageBodyElement );
391         int err = MsgErrNoError;
392
393         QDomNode base = constructArrayToNode( reqCmdArrayEnvelopeBase, size );
394
395         if( !base.isNull() )
396                 err = addNode( base );
397         else err = MsgErrSomeError;
398
399 #ifdef MU_DEBUG
400         qDebug( "RequestMessage::createEnvelopeBase end : err=%d", err );
401 #endif          
402         return err;
403 }
404
405 QString RequestMessage::getContentTypeForHeader( RequestCommandId aCommandId )
406 {
407 #ifdef MU_DEBUG
408         qDebug( "RequestMessage::getContentTypeForHeader" );
409 #endif
410         QString contentType( QString::null );
411
412         RequestCommandId cmd = ( aCommandId == ReqCmdNoCommand ) ? iCurrCmd : aCommandId;
413
414         if( cmd != ReqCmdNoCommand )
415         {
416                 QString operation( QString::null );
417                 switch( cmd )
418                 {
419                 //Used commands
420                 case ReqCmdGetUserAvailability : { operation = "GetUserAvailability"; } break;
421                 case ReqCmdConvertId : { operation = "ConvertId"; } break;
422                 case ReqCmdGetItem : { operation = "GetItem"; } break;
423
424                 //Currently unused operations
425
426                 /*case ReqCmdAddDelegate : { operation = "AddDelegate"; } break;
427                 case ReqCmdCopyFolder : { operation = "CopyFolder"; } break;
428                 case ReqCmdCopyItem : { operation = "CopyItem"; } break;
429                 case ReqCmdCreateAttachment : { operation = "CreateAttachment"; } break;
430                 case ReqCmdCreateFolder : { operation = "CreateFolder"; } break;
431                 case ReqCmdCreateItem : { operation = "CreateItem"; } break;
432                 case ReqCmdCreateManagedFolder : { operation = "CreateManagedFolder"; } break;
433                 case ReqCmdDeleteAttachment : { operation = "DeleteAttachment"; } break;
434                 case ReqCmdDeleteFolder : { operation = "DeleteFolder"; } break;
435                 case ReqCmdDeleteItem : { operation = "DeleteItem"; } break;
436                 case ReqCmdExpandDL : { operation = "ExpandDL"; } break;
437                 case ReqCmdFindFolder : { operation = "FindFolder"; } break;
438                 case ReqCmdFindItem : { operation = "FindItem"; } break;
439                 case ReqCmdGetAttachment : { operation = "GetAttachment"; } break;
440                 case ReqCmdGetDelegate : { operation = "GetDelegate"; } break;
441                 case ReqCmdGetEvents : { operation = "GetEvents"; } break;
442                 case ReqCmdGetFolder : { operation = "GetFolder"; } break;
443                 case ReqCmdGetUserOofSettings : { operation = "GetUserOofSettings"; } break;
444                 case ReqCmdMoveFolder : { operation = "MoveFolder"; } break;
445                 case ReqCmdMoveItem : { operation = "MoveItem"; } break;
446                 case ReqCmdRemoveDelegate : { operation = "RemoveDelegate"; } break;
447                 case ReqCmdResolveNames : { operation = "ResolveNames"; } break;
448                 case ReqCmdSendItem : { operation = "SendItem"; } break;
449                 case ReqCmdSetUserOofSettings : { operation = "SetUserOofSettings"; } break;
450                 case ReqCmdSubscribe : { operation = "Subscribe"; } break;
451                 case ReqCmdSyncFolderHierarchy : { operation = "SyncFolderHierarchy"; } break;
452                 case ReqCmdSyncFolderItems : { operation = "SyncFolderItems"; } break;
453                 case ReqCmdUnsubscribe : { operation = "Unsubscribe"; } break;
454                 case ReqCmdUpdateDelegate : { operation = "UpdateDelegate"; } break;
455                 case ReqCmdUpdateFolder : { operation = "UpdateFolder"; } break;
456                 case ReqCmdUpdateItem : { operation = "UpdateItem"; } break;*/
457                 default: break;
458                 };
459
460                 if( operation != QString::null )
461                 {
462                         QString content( "text/xml; " );
463                         QString charset( "utf-8; " );
464                         contentType = QString( content + "charset=" + charset + "action=\"" + ACTION_URL + operation + "\"" );
465                 }
466         }
467 #ifdef MU_DEBUG
468         qDebug( "RequestMessage::getContentTypeForHeader end : contentType=%s", contentType.toStdString().data() );
469 #endif          
470         return contentType;
471 }
472
473 int RequestMessage::createMessageStructure()
474 {
475         return createMessageStructure( iCurrCmd );
476 }
477
478 int RequestMessage::createMessageStructure( RequestCommandId aCommandId )
479 {
480 #ifdef MU_DEBUG
481         qDebug( "RequestMessage::createMessageStructure" );
482 #endif
483         if( !iMessage )
484         {
485 #ifdef MU_DEBUG
486         qDebug( "RequestMessage::createMessageStructure : iMessage is NULL" );
487 #endif          
488                 return MsgErrSomeError;
489         }
490
491         //Should always be soap:Envelope or first element in envelopebase array
492         QDomNode last = iMessage->documentElement();
493
494         if( !matchName( last, reqCmdArrayEnvelopeBase[0].iElementName ) )
495         {
496 #ifdef MU_DEBUG
497         qDebug( "RequestMessage::createMessageStructure : Document element is not valid SOAP envelope" );
498 #endif          
499                 return MsgErrSomeError;
500         }
501
502         QDomNode cmd;
503         int err = MsgErrNoError;
504
505         switch( aCommandId )
506         {
507         case ReqCmdGetUserAvailability : { cmd = constructArrayToNode( reqCmdArrayGetUserAvailability, sizeof( reqCmdArrayGetUserAvailability ) / sizeof( MessageBodyElement ) ); } break;
508         case ReqCmdConvertId : { cmd = constructArrayToNode( reqCmdArrayConvertId, sizeof( reqCmdArrayConvertId ) / sizeof( MessageBodyElement ) ); } break;
509         case ReqCmdGetItem : { cmd = constructArrayToNode( reqCmdArrayGetCalendarItem, sizeof( reqCmdArrayGetCalendarItem ) / sizeof( MessageBodyElement ) ); } break;
510         default: break;
511         };
512
513         if( cmd.isNull() ) err = MsgErrSomeError;
514         else{
515                 err = addNode( cmd, QDomNode::ElementNode, reqCmdArrayEnvelopeBase[0].iElementName );
516         }
517 #ifdef MU_DEBUG
518         qDebug( "RequestMessage::createMessageStructure end : err=%d", err );
519 #endif  
520         return err;
521 }
522
523 QDomNode RequestMessage::constructArrayToNode( const MessageBodyElement* aArray, int aSize )
524 {
525 #ifdef MU_DEBUG
526         qDebug( "RequestMessage::constructArrayToNode" );
527 #endif
528         QDomElement target; //final node to be returned
529
530         if( !iMessage || aSize == 0 )
531                 {
532 #ifdef MU_DEBUG
533         qDebug( "RequestMessage::constructArrayToNode : iMessage is NULL or aSize is 0." );
534 #endif
535                 return target;
536                 }
537
538         QDomElement last; // last appended node
539
540         int currentLvl = 0; //current traversal level
541         int idx = 0;
542
543         //get the root
544         MessageBodyElement root = aArray[idx];
545         if( root.iNodeType != QDomNode::ElementNode || root.iTraversalLevel > 0 )
546         {
547 #ifdef MU_DEBUG
548         qDebug( "RequestMessage::constructArrayToNode : Malformed message definition. Check array for faults." );
549 #endif          
550                 return target; //Root must be an element and on level 0
551         }
552         else
553         {
554                 if( root.iNamespace != QString::null )
555                 {
556                         //QString prefix = root.iNamespace
557                         target = iMessage->createElementNS( root.iNamespace, root.iElementName );
558                 }
559                 else
560                 {
561                         target = iMessage->createElement( root.iElementName );
562                 }
563                 last = target;
564                 idx++;
565         }
566
567         for( int i=idx; i<aSize; i++ )
568         {
569                 MessageBodyElement element = aArray[i];
570
571                 if( element.iNodeType == QDomNode::ElementNode )
572                 {
573                         //Node is an element node
574                         QDomElement elem;
575                         if( element.iNamespace != QString::null )
576                         {
577                                 elem = iMessage->createElementNS( element.iNamespace, element.iElementName );
578                         }
579                         else
580                         {
581                                 elem = iMessage->createElement( element.iElementName );
582                         }
583                         if( element.iTraversalLevel == currentLvl )
584                         {
585                                 if( currentLvl == 0 )
586                                 {
587 #ifdef MU_DEBUG
588         qDebug( "RequestMessage::constructArrayToNode : Malformed message definition. Check array for faults." );
589 #endif                                                  
590                                         return target; //Only root can be at traversal level 0
591                                 }
592                                 else
593                                 {
594                                         //Sibling to previous
595                                         if( !last.parentNode().isNull() )
596                                                 last.parentNode().appendChild( elem );
597                                         else
598                                                 {
599 #ifdef MU_DEBUG
600         qDebug( "RequestMessage::constructArrayToNode : Malformed message definition. Check array for faults." );
601 #endif  
602                                                 return target; //malformed. if last has no parent, it's a rootnode
603                                                 }
604                                 }
605                         }
606                         else if( element.iTraversalLevel > currentLvl )
607                         {
608                                 //check if node is child to previous
609                                 //else there is something wrong in array representing the structure
610                                 if( element.iTraversalLevel == currentLvl+1 )
611                                 {
612                                         last.appendChild( elem );
613                                 }
614                                 else
615                                 {
616 #ifdef MU_DEBUG
617         qDebug( "RequestMessage::constructArrayToNode : Malformed message definition. Check array for faults." );
618 #endif  
619                                         return target;
620                                 }
621                         }
622                         else if( element.iTraversalLevel < currentLvl )
623                         {
624
625                                 //Node is on more shallow level than previous
626                                 //let's get it's parent
627                                 int diff = currentLvl - element.iTraversalLevel;
628
629                                 for( int j=0; j<diff; j++ )
630                                 {
631                                         QDomNode temp = last.parentNode();
632                                         last = temp.toElement();
633                                 }
634                                 last.parentNode().appendChild( elem );
635                         }
636                         else
637                         {
638 #ifdef MU_DEBUG
639         qDebug( "RequestMessage::constructArrayToNode : Malformed message definition. Check array for faults." );
640 #endif                          
641                                 //some undefined error
642                                 return target;
643                         }
644
645                         last = elem;
646                 }
647                 else if( element.iNodeType == QDomNode::AttributeNode )
648                 {
649                         //Node is an attribute node
650
651                         QDomAttr attr;
652                         if( element.iNamespace != QString::null )
653                                  attr = iMessage->createAttributeNS( element.iNamespace, element.iElementName );
654                         else
655                                  attr = iMessage->createAttribute( element.iElementName );
656
657                         if( element.iTraversalLevel == currentLvl )
658                         {
659                                 last.setAttributeNode( attr );
660                         }
661                         else
662                         {
663 #ifdef MU_DEBUG
664         qDebug( "RequestMessage::constructArrayToNode : Malformed message definition. Check array for faults." );
665 #endif                                  
666                                 //error in template array.
667                                 //attributes for element must be specified right after element
668                                 //and must have same traversalId
669                                 return target;
670                         }
671                 }
672                 else
673                 {
674 #ifdef MU_DEBUG
675         qDebug( "RequestMessage::constructArrayToNode : Node type not supported." );
676 #endif  
677                         //node type not supported
678                         return target;
679                 }
680
681                 currentLvl = element.iTraversalLevel;
682         }
683 #ifdef MU_DEBUG
684         qDebug( "RequestMessage::constructArrayToNode : end" );
685 #endif  
686         return target;
687 }
688
689 /*
690  * ResponseMessage class functions
691  */
692 ResponseMessage::ResponseMessage()
693 {
694 #ifdef MU_DEBUG
695         qDebug( "ResponseMessage::ResponseMessage" );
696 #endif
697         iMessage = new QDomDocument();
698 #ifdef MU_DEBUG
699         qDebug( "ResponseMessage::ResponseMessage end" );
700 #endif
701 }
702
703 ResponseMessage::ResponseMessage( const QByteArray& aData )
704 {
705 #ifdef MU_DEBUG
706         qDebug( "ResponseMessage::ResponseMessage" );
707 #endif
708         iMessage->setContent( aData, true );
709 #ifdef MU_DEBUG
710         qDebug( "ResponseMessage::ResponseMessage end" );
711 #endif
712 }
713
714 QString ResponseMessage::getNodeValue( const QString& aNodeName, QDomNode::NodeType aNodeType, const QString& aParentName, int aIndex, QDomNode* aRootNode )
715 {
716 #ifdef MU_DEBUG
717         qDebug( "ResponseMessage::getNodeValue" );
718 #endif  
719         QString value = QString::null;
720         QDomNode node = getNodeFromDocument( aNodeName, aNodeType, aParentName, aIndex, aRootNode );
721         if( !node.isNull() )
722         {
723                 if( node.isElement() )
724                         value = node.toElement().text();
725                 else if( node.isAttr() )
726                         value = node.toAttr().value();
727         }
728 #ifdef MU_DEBUG
729         qDebug( "ResponseMessage::getNodeValue end" );
730 #endif  
731         return value;   
732 }
733
734 bool ResponseMessage::hasErrors()
735 {
736 #ifdef MU_DEBUG
737         qDebug( "ResponseMessage::hasErrors" );
738 #endif
739         if( !iMessage )
740                 {
741 #ifdef MU_DEBUG
742         qDebug( "ResponseMessage::hasErrors : iMessage is NULL." );
743 #endif
744                 return true;
745                 }
746
747         QDomElement root = iMessage->documentElement();
748         bool err = false;
749
750         QString rootname = ( root.prefix() == QString::null ) ? root.tagName() : root.localName();
751         err = ( rootname.compare( QString( "Envelope" ) ) == 0 ) ? false : true;
752
753         QDomNodeList list = iMessage->elementsByTagName( QString( "m:ResponseCode" ) );
754         for( int i=0; i<list.count(); i++ )
755         {
756                 if( list.item(i).nodeValue().compare( "NoError" ) != 0 )
757                         {
758                         err = true;
759                         }
760         }
761 #ifdef MU_DEBUG
762         qDebug( "ResponseMessage::hasErrors end : err=%d", err );
763 #endif  
764         return err;
765 }
766
767 /*
768  * ReqMsgGetUserAvailability class functions
769  */
770
771 ReqMsgGetUserAvailability::ReqMsgGetUserAvailability() : RequestMessage( ReqCmdGetUserAvailability )
772 {
773 #ifdef MU_DEBUG
774         qDebug( "ReqMsgGetUserAvailability::ReqMsgGetUserAvailability" );
775 #endif
776         if( iMessage && iCurrCmd == ReqCmdGetUserAvailability )
777         {
778                 setNodeValue( QString( "MergedFreeBusyIntervalInMinutes" ), QString::number( 60 ) );
779                 setNodeValue( QString( "RequestedView" ), QString( "DetailedMerged" ) );
780         }
781 #ifdef MU_DEBUG
782         qDebug( "ReqMsgGetUserAvailability::ReqMsgGetUserAvailability end" );
783 #endif  
784 }
785
786 int ReqMsgGetUserAvailability::addUser( const QString& aAddress, const QString& /*aAttendeeType*/, const QString& aExcludeConflicts )
787 {
788 #ifdef MU_DEBUG
789         qDebug( "ReqMsgGetUserAvailability::addUser" );
790 #endif
791         if( !iMessage || iCurrCmd != ReqCmdGetUserAvailability )
792         {
793 #ifdef MU_DEBUG
794         qDebug( "ReqMsgGetUserAvailability::addUser : iMessage is NULL or current command id is wrong" );
795 #endif          
796                 return MsgErrSomeError;
797         }
798
799         int err = MsgErrNoError;
800         int size = sizeof( reqCmdMailboxElement ) / sizeof( MessageBodyElement );
801
802         //Create mailbox data element
803         QDomNode mailbox = constructArrayToNode( reqCmdMailboxElement, size );
804         if( !mailbox.isNull() )
805         {
806                 QDomNode email;
807
808                 if( mailbox.hasChildNodes() )
809                 {
810                         for ( QDomNode subnode = mailbox.firstChild(); !subnode.isNull(); subnode = subnode.nextSibling() )
811                         {
812                                 qDebug( "subnode: %s", subnode.toElement().tagName().toStdString().data() );
813                                 if( matchName( subnode, QString( "Email" ) ) )
814                                         {
815                                         email = subnode;
816                                         }
817                         }
818                 }
819
820                 setNodeValue( QString( "Address" ), aAddress, QDomNode::ElementNode, QString( "Email" ), 0, &email );
821                 setNodeValue( QString( "AttendeeType" ), QString( "Required" ), QDomNode::ElementNode, QString( "MailboxData" ), 0, &mailbox );
822                 setNodeValue( QString( "ExcludeConflicts" ), aExcludeConflicts, QDomNode::ElementNode, QString( "MailboxData" ), 0, &mailbox );
823
824                 err = addNode( mailbox, QDomNode::ElementNode, QString( "MailboxDataArray" ) );
825         }
826         else
827                 err = MsgErrSomeError;
828
829 #ifdef MU_DEBUG
830         qDebug( "ReqMsgGetUserAvailability::addUser end : err=%d", err );
831 #endif  
832         return err;
833 }
834
835 int ReqMsgGetUserAvailability::setTimeWindow( const QDateTime& aStart, const QDateTime& aEnd )
836 {
837 #ifdef MU_DEBUG
838         qDebug( "ReqMsgGetUserAvailability::setTimeWindow" );
839 #endif
840         if( !iMessage || iCurrCmd != ReqCmdGetUserAvailability )
841         {
842 #ifdef MU_DEBUG
843         qDebug( "ReqMsgGetUserAvailability::setTimeWindow : iMessage is NULL or command id is wrong" );
844 #endif          
845                 return MsgErrSomeError;
846         }
847
848         int err = MsgErrNoError;
849
850         err = setNodeValue( QString( "StartTime" ), aStart.toString( Qt::ISODate ) );
851         err = setNodeValue( QString( "EndTime" ), aEnd.toString( Qt::ISODate ) );
852
853 #ifdef MU_DEBUG
854         qDebug( "ReqMsgGetUserAvailability::setTimeWindow end : err=%d", err );
855 #endif          
856         return err;
857 }
858
859 int ReqMsgGetUserAvailability::setTimeZone()
860 {
861 #ifdef MU_DEBUG
862         qDebug( "ReqMsgGetUserAvailability::setTimeZone" );
863 #endif
864         if( !iMessage || iCurrCmd != ReqCmdGetUserAvailability )
865         {
866 #ifdef MU_DEBUG
867         qDebug( "ReqMsgGetUserAvailability::setTimeZone : iMessage is NULL or command id is wrong" );
868 #endif          
869                 return MsgErrSomeError;
870         }
871         int err = MsgErrNoError;
872         
873         //QDateTime now = QDateTime::currentDateTime();
874         //int offsetMinutes =  (now.toTime_t() - QDateTime(now.toUTC().date(), QTime(now.toUTC().time().hour(), now.toUTC().time().minute())).toTime_t()) / 60;
875         
876         time_t rawtime;
877         tm *localTime;
878
879         time(&rawtime);
880         localTime = localtime(&rawtime);
881         
882         int offsetMinutes = localTime->tm_gmtoff / 60;
883         if (localTime->tm_isdst)
884                 offsetMinutes -= 60;    // If DST is in use then reduce an hour from offset, because
885                                                                 // DST will be added to the offset later and it already includes
886                                                                 // DST. TODO: This is silly and must be changed if possible.
887                                                                 // If you can get UTC offset without DST, use it here.
888         
889 #ifdef MU_DEBUG
890         qDebug( "ReqMsgGetUserAvailability::setTimeZone - offset in minutes=%d", offsetMinutes );
891 #endif
892         
893         //TODO: timezone and daylight times to application configuration
894         setNodeValue( QString( "Bias" ), QString::number( -offsetMinutes ), QDomNode::ElementNode, QString( "TimeZone" ) );
895         setNodeValue( QString( "Bias" ), QString::number( 0 ), QDomNode::ElementNode, QString( "StandardTime" ) );
896         setNodeValue( QString( "Time" ), QString( "03:00:00" ), QDomNode::ElementNode, QString( "StandardTime" ) );
897         setNodeValue( QString( "DayOrder" ), QString::number( 5 ), QDomNode::ElementNode, QString( "StandardTime" ) );
898         setNodeValue( QString( "Month" ), QString::number( 10 ), QDomNode::ElementNode, QString( "StandardTime" ) );
899         setNodeValue( QString( "DayOfWeek" ), QString( "Sunday" ), QDomNode::ElementNode, QString( "StandardTime" ) );
900         setNodeValue( QString( "Bias" ), QString::number( -60 ), QDomNode::ElementNode, QString( "DaylightTime" ) );
901         setNodeValue( QString( "Time" ), QString( "03:00:00" ), QDomNode::ElementNode, QString( "DaylightTime" ) );
902         setNodeValue( QString( "DayOrder" ), QString::number( 1 ), QDomNode::ElementNode, QString( "DaylightTime" ) );
903         setNodeValue( QString( "Month" ), QString::number( 4 ), QDomNode::ElementNode, QString( "DaylightTime" ) );
904         setNodeValue( QString( "DayOfWeek" ), QString( "Sunday" ), QDomNode::ElementNode, QString( "DaylightTime" ) );
905
906 #ifdef MU_DEBUG
907         qDebug( "ReqMsgGetUserAvailability::setTimeZone end : err=%d", err );
908 #endif          
909         return err;
910 }
911
912 /*
913  * ReqMsgConvertMeetingId class functions
914  */
915 ReqMsgConvertMeetingId::ReqMsgConvertMeetingId( const QString& aItemId, const QString& aMailbox )
916 {
917 #ifdef MU_DEBUG
918         qDebug( "ReqMsgConvertMeetingId::ReqMsgConvertMeetingId" );
919 #endif  
920         //For this class, we're not going to provide id for base class as parameter,
921         //because before content structure initialization, we must add SOAP header to envelope
922         iCurrCmd = ReqCmdConvertId;
923         
924         QDomNode header = constructArrayToNode( reqCmdArrayConvertIdHeader, sizeof( reqCmdArrayConvertIdHeader ) / sizeof( MessageBodyElement ) );
925         
926         if( !header.isNull() )
927         {
928                 int err = addNode( header, QDomNode::ElementNode, reqCmdArrayEnvelopeBase[0].iElementName );
929
930                 if( err == MsgErrNoError )
931                 {
932                 createMessageStructure( ReqCmdConvertId );
933                 
934                 if( aItemId != QString::null ) setItemId( aItemId );
935                 if( aMailbox != QString::null ) setMailbox( aMailbox );
936                 
937                 setNodeValue( QString( "Version" ), QString( "Exchange2007_SP1" ), QDomNode::AttributeNode, QString( "RequestServerVersion" ) );
938                 setNodeValue( QString( "DestinationFormat" ), QString( "EwsLegacyId" ), QDomNode::AttributeNode, QString( "ConvertId" ) );
939                 setNodeValue( QString( "Format" ), QString( "HexEntryId" ), QDomNode::AttributeNode, QString( "AlternateId" ) );
940                 }
941         }
942         //setNodeValue( QString( "xmlns:t" ), NS_T, QDomNode::AttributeNode, QString( "ConvertId" ) );
943         
944         //Must be added (for now at least) like this, because Envelope is initialized already, without attributes
945         /*QDomAttr attr = iMessage->createAttribute( QString( "xmlns:t" ) );
946         attr.setValue( NS_T );
947         addNode( attr, QDomNode::AttributeNode, QString( "Envelope" ) );
948         */
949 #ifdef MU_DEBUG
950         qDebug( "ReqMsgConvertMeetingId::ReqMsgConvertMeetingId end" );
951 #endif          
952 }
953
954 int ReqMsgConvertMeetingId::setItemId( const QString& aItemId )
955 {
956 #ifdef MU_DEBUG
957         qDebug( "ReqMsgConvertMeetingId::setItemId" );
958 #endif  
959         int err = setNodeValue( QString( "Id" ), aItemId, QDomNode::AttributeNode, QString( "AlternateId" ) );
960 #ifdef MU_DEBUG
961         qDebug( "ReqMsgConvertMeetingId::setItemId end : err=%d", err );
962 #endif  
963         return err;
964 }
965
966 int ReqMsgConvertMeetingId::setMailbox( const QString& aMailbox )
967 {
968 #ifdef MU_DEBUG
969         qDebug( "ReqMsgConvertMeetingId::setMailbox" );
970 #endif  
971         int err = setNodeValue( QString( "Mailbox" ), aMailbox, QDomNode::AttributeNode, QString( "AlternateId" ) );
972 #ifdef MU_DEBUG
973         qDebug( "ReqMsgConvertMeetingId::setMailbox end : err=%d", err );
974 #endif
975         return err;
976 }
977
978 /*
979  * ReqMsgGetCalendarItem class functions
980  */
981 ReqMsgGetCalendarItem::ReqMsgGetCalendarItem( const QString& aItemId ) : RequestMessage( ReqCmdGetItem )
982 {
983 #ifdef MU_DEBUG
984         qDebug( "ReqMsgGetCalendarItem::ReqMsgGetCalendarItem" );
985 #endif  
986         if( iMessage && iCurrCmd == ReqCmdGetItem )
987         {
988                 setNodeValue( QString( "BaseShape" ), QString( "AllProperties" ) );
989                 
990                 if( aItemId != QString::null )
991                         setItemId( aItemId );
992         }
993 #ifdef MU_DEBUG
994         qDebug( "ReqMsgGetCalendarItem::ReqMsgGetCalendarItem end" );
995 #endif
996 }
997
998 int ReqMsgGetCalendarItem::setItemId( const QString& aItemId )
999 {
1000 #ifdef MU_DEBUG
1001         qDebug( "ReqMsgGetCalendarItem::setItemId" );
1002 #endif  
1003         int err = setNodeValue( QString( "Id" ), aItemId, QDomNode::AttributeNode, QString( "ItemId" ), 0 );
1004 #ifdef MU_DEBUG
1005         qDebug( "ReqMsgGetCalendarItem::setItemId end : err=%d", err );
1006 #endif  
1007         return err;
1008 }
1009
1010 /*
1011  * ResMsgGetUserAvailability class functions
1012  */
1013 ResMsgGetUserAvailability::ResMsgGetUserAvailability( const QByteArray& aData ) : ResponseMessage( aData )
1014 {
1015 #ifdef MU_DEBUG
1016         qDebug( "ResMsgGetUserAvailability::ResMsgGetUserAvailability" );
1017         qDebug( "ResMsgGetUserAvailability::ResMsgGetUserAvailability end" );
1018 #endif
1019 }
1020
1021 int ResMsgGetUserAvailability::getMeetingsFromResponse( QList<Meeting*>& aMeetings, const Room &aRoom )
1022 {
1023 #ifdef MU_DEBUG
1024         qDebug( "ResMsgGetUserAvailability::getMeetingsFromResponse" );
1025 #endif
1026                 if( !iMessage )
1027                         {
1028 #ifdef MU_DEBUG
1029         qDebug( "ResMsgGetUserAvailability::getMeetingsFromResponse : iMessage is NULL" );
1030 #endif  
1031                         return MsgErrSomeError;
1032                         }
1033
1034                 //TODO: Clean this function a bit (see getMeetingDetailsFromResponse)
1035                 
1036                 int err = MsgErrNoError;
1037
1038                 QDomNodeList list = iMessage->elementsByTagName( QString( "CalendarEvent" ) );
1039
1040                 for( int i=0; i<list.count(); i++ )
1041                 {
1042                         QDomElement e = list.item( i ).toElement();
1043                         QString tagName = ( e.prefix() == QString::null ) ? e.tagName().toLower() : e.localName().toLower();
1044
1045                         if( !e.isNull() && tagName == "calendarevent" )
1046                         {
1047
1048                                 QString id, startsAt, endsAt, organizer, subject;
1049
1050                                 for ( QDomNode subnode = e.firstChild(); !subnode.isNull(); subnode = subnode.nextSibling() )
1051                                 {
1052                                         QDomElement e = subnode.toElement();
1053                                         QString tagName = ( e.prefix() == QString::null ) ? e.tagName().toLower() : e.localName().toLower();
1054
1055                                         if( tagName == QString( "starttime" ) )
1056                                         {
1057                                                 startsAt = e.text();
1058                                         }
1059                                         else if( tagName == QString( "endtime" ) )
1060                                         {
1061                                                 endsAt = e.text();
1062                                         }
1063                                         else if( tagName == QString( "calendareventdetails" ) )
1064                                         {
1065
1066                                                 for ( QDomNode detailnode = subnode.firstChild(); !detailnode.isNull(); detailnode = detailnode.nextSibling() )
1067                                                 {
1068
1069                                                         QDomElement e = detailnode.toElement();
1070                                                         QString tagName = ( e.prefix() == QString::null ) ? e.tagName().toLower() : e.localName().toLower();
1071
1072                                                         if( tagName == QString( "id" ) )
1073                                                         {                                                       
1074                                                                 id = e.text();
1075                                                         }
1076
1077                                                         if( tagName == QString( "subject" ) )
1078                                                         {
1079                                                                 subject = e.text();
1080                                                         }
1081                                                 }
1082                                         }
1083                                 }
1084
1085                                 QDateTime start = QDateTime::fromString( startsAt, Qt::ISODate );
1086                                 QDateTime end = QDateTime::fromString( endsAt, Qt::ISODate );
1087
1088                                 aMeetings.append( new Meeting(
1089                                                 id,
1090                                                 aRoom,
1091                                                 start,
1092                                                 end,
1093                                                 subject ) );
1094
1095                         }
1096                 }
1097 #ifdef MU_DEBUG
1098         qDebug( "ResMsgGetUserAvailability::getMeetingsFromResponse end : err=%d", err );
1099 #endif          
1100                 return err;
1101 }
1102
1103 /*
1104  * ResMsgGetCalendarItem class functions
1105  */
1106 int ResMsgGetCalendarItem::getMeetingDetailsFromResponse( Meeting& aMeeting )
1107 {
1108 #ifdef MU_DEBUG
1109         qDebug( "ResMsgGetCalendarItem::getMeetingDetailsFromResponse" );
1110 #endif
1111         if( !iMessage || hasErrors() )
1112                 {
1113 #ifdef MU_DEBUG
1114         qDebug( "ResMsgGetCalendarItem::getMeetingDetailsFromResponse : iMessage is NULL or response has errors." );
1115 #endif          
1116                 return MsgErrSomeError;
1117                 }
1118
1119         QString name, address, description; //Organizer
1120
1121         QDomNode box = getElementFromDocument( QString( "Mailbox" ), QString( "Organizer" ), 0 );
1122
1123         if( !box.isNull() && box.hasChildNodes() )
1124         {
1125                 for ( QDomNode subnode = box.firstChild(); !subnode.isNull(); subnode = subnode.nextSibling() )
1126                 {
1127                         if( matchName( subnode, QString( "Name" ) ) )
1128                                 name = subnode.toElement().text();
1129                         else if( matchName( subnode, QString( "EmailAddress" ) ) )
1130                                 address = subnode.toElement().text();
1131                 }
1132         }
1133         
1134         QDomNode body = getElementFromDocument( QString( "Body" ), QString( "CalendarItem" ), 0 );
1135
1136         if( body.isElement() )
1137                 description = body.toElement().text();
1138         
1139         aMeeting.setOrganizer( name, address );
1140         aMeeting.setDescription( description );
1141
1142 #ifdef MU_DEBUG
1143         qDebug( "ResMsgGetCalendarItem::getMeetingDetailsFromResponse end" );
1144 #endif          
1145         return MsgErrNoError;
1146 }
1147