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