Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Messaging / Email.cpp
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. 
15 */
16
17
18 /**
19  *
20  *
21  * @file       Email.cpp
22  * @author     Pawel Misiak (p.misiak@samsung.com)
23  * @version    0.1
24  * @brief
25  */
26 #include <cstdio>
27 #include <cstddef>
28 #include <cstdlib>
29 #include <ctime>
30 #include <emf-types.h>
31 #include <Emf_Mapi.h>
32 #include <dpl/log/log.h>
33 #include <dpl/assert.h>
34 #include <dpl/scoped_fclose.h>
35 #include <dpl/scoped_ptr.h>
36 #include <Commons/Exception.h>
37 #include <Commons/StringUtils.h>
38 #include <API/Messaging/MessageFactory.h>
39 #include "Messaging.h"
40 #include "Email.h"
41 #include "EmailService.h"
42 #include "EmailUtils.h"
43 #include "EmailConverter.h"
44 #include "MailSender.h"
45 #include "MailSync.h"
46 #include "MessagingService.h"
47 #include "MessagingServiceManager.h"
48 #include "Attachment.h"
49
50 #define LOG_ENTER LogDebug("---> ENTER");
51 #define LOG_EXIT LogDebug("---> EXIT");
52
53 using namespace std;
54 using namespace TizenApis::Api::Messaging;
55 using namespace WrtDeviceApis::Commons;
56
57 namespace TizenApis {
58 namespace Platform {
59 namespace Messaging {
60
61 #if 0 // UNUSED CODE
62 namespace {
63 //#define USE_OUTBOX
64
65 #ifdef USE_OUTBOX
66 const Api::Messaging::FolderType DEFAULT_FOLDER = Api::Messaging::OUTBOX;
67 const char* DEFAULT_FOLDER_NAME = EMF_OUTBOX_NAME;
68 #else
69 const Api::Messaging::FolderType DEFAULT_FOLDER = Api::Messaging::DRAFTBOX;
70 const char* DEFAULT_FOLDER_NAME = EMF_DRAFTBOX_NAME;
71 #endif
72 }
73 #endif
74
75 namespace {
76 const char* TEMP_FOLDER = "/tmp";
77 const char* COMMAND_NAME = "/bin/cp";
78 const char* COMMAND_SWITCH_RECURSIVE = "-r";
79 const char* COMMAND_SWITCH_FORCE = "-f";
80 }
81
82 Email::Email(const string& id) :
83         IMessage(EMAIL, id) {
84         LOG_ENTER
85
86         try {
87                 if (getIdRef().empty()) {
88                         //exception
89                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, " message id is invalid");
90                 }
91                                 
92                 reload();
93         } catch (const WrtDeviceApis::Commons::PlatformException& ex) {
94                 LogError("Exception: " << ex.DumpToString());
95         }
96
97         LOG_EXIT
98 }
99
100 Email::Email(const std::string& id, int accountId) :
101         IMessage(EMAIL, id) 
102 {
103         LOG_ENTER
104
105         try {
106                 if (getIdRef().empty()) {
107                         //exception
108                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, " message id is invalid");
109                 }
110                 
111                 LogDebug("Account ID = " << accountId);
112                 m_accountId = accountId;
113                 reload();
114                 
115         } catch (const WrtDeviceApis::Commons::PlatformException& ex) {
116                 LogError("Exception: " << ex.DumpToString());
117         }
118
119
120         LOG_EXIT
121 }
122
123 Email::Email(Api::Messaging::EmailAccountInfo& account) : IMessage(EMAIL)
124 {
125     LOG_ENTER
126
127     try {
128          if (getIdRef().empty()) {
129                 create(account);
130          }
131         
132         reload();
133     }
134     catch (const WrtDeviceApis::Commons::PlatformException& ex) {
135         LogError("Exception: " << ex.DumpToString());
136     }
137
138     LOG_EXIT
139 }
140
141 Email::Email(const Api::Messaging::FolderType folder) : IMessage(EMAIL)
142 {
143     LOG_ENTER
144
145     try {
146          if (folder == Api::Messaging::TEMP_FOLDER) {
147                 create();
148          }
149            else {
150               ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Folder Type is miss-matched");
151            }
152     }
153     catch (const WrtDeviceApis::Commons::PlatformException& ex) {
154         LogError("Exception: " << ex.DumpToString());
155     }
156
157     LOG_EXIT
158 }
159
160 Email::~Email()
161 {
162     LogDebug("ENTER");
163 }
164
165 int Email::send()
166 {
167     LOG_ENTER
168
169     update();
170
171     int handle = MailSender::getInstance().send(
172         Api::Messaging::MessageFactory::convertToEmail(SharedFromThis())
173         );
174
175     return handle;
176     LOG_EXIT
177 }
178
179 void Email::sendCancel(int handle)
180 {
181     LOG_ENTER
182
183     MailSender::getInstance().cancel(handle);
184
185     LOG_EXIT
186 }
187
188 int Email::downloadBody()
189 {
190         LOG_ENTER
191
192         return MailSync::getInstance().downloadBody( Api::Messaging::MessageFactory::convertToEmail(SharedFromThis()) );
193         
194         LOG_EXIT
195 }
196
197 void Email::downloadBodyCancel( int handle)
198 {       
199         
200         return ;
201 }
202
203 int Email::downloadAttachment( const Api::Messaging::IAttachmentPtr& attachment)
204 {
205         LOG_ENTER
206
207         return MailSync::getInstance().downloadAttachment( Api::Messaging::MessageFactory::convertToEmail(SharedFromThis()), attachment );
208         
209         LOG_EXIT
210 }
211
212 void Email::update(bool draftsOnly)
213 {
214     LOG_ENTER
215
216     DPL::Mutex::ScopedLock mx(&m_updateMutex);
217
218     if (!m_mail) {
219         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
220     }
221
222     LogDebug("getCurrentFolder() = " << getCurrentFolder() );
223     if (!draftsOnly || (getCurrentFolder() == Api::Messaging::DRAFTBOX)) {
224         updateBody();
225         updateSubject();
226         updateRecipients();
227         updateFrom();
228         updateAttachments();
229         updatePriority();
230     } else {
231         LogWarning("Updating only read status. Folder: " << getCurrentFolder());
232     }
233     updateReadStatus();
234
235     int error = email_update_message(getIntId(), m_mail.Get());
236     if (EMF_ERROR_NONE != error) {
237         LogWarning("Nothing to update or error. [" << error << "]");
238     }
239
240     LOG_EXIT
241 }
242
243 int Email::getAccountID()
244 {
245         LOG_ENTER
246
247         if ( m_mail )
248                 return m_mail->info->account_id;
249         else
250                 return -1;
251         
252         LOG_EXIT
253 }
254
255 int Email::getUID()
256 {
257         LOG_ENTER
258         
259         if (m_mail)
260                 return m_mail->info->uid;
261         else
262                 return -1;
263
264         LOG_EXIT
265 }
266
267 int Email::isBodyDownloaded()
268 {
269         
270         if (m_mail)
271                 return m_mail->info->body_downloaded;
272         else
273                 return false;
274 }
275
276 bool Email::hasAttachment()
277 {       
278         std::size_t attachmentSize = getAttachmentsCount();
279         if ( attachmentSize > 0)
280                         return true;
281                 else
282                         return false;
283 }
284
285 void Email::readAllData()
286 {
287     reload();
288 }
289
290 void Email::moveToFolder(const FolderType newFolder)
291 {
292     LOG_ENTER
293
294     moveToFolder(EmailConverter::toMailboxName(newFolder));
295
296     LOG_EXIT
297 }
298
299 void Email::moveToFolder(const string& newFolder)
300 {
301     update();
302
303     int accountId = Messaging::getInstance().getEmailAccountId(getFromRef());
304     ScopedMailbox mailbox(
305         EmailService::createMailbox(accountId, newFolder.c_str())
306         );
307
308     int mailId = getIntId();
309
310     int error = email_move_mail_to_mailbox(&mailId, 1, mailbox.Get());
311     if (EMF_ERROR_NONE != error) {
312         ThrowMsg(
313             WrtDeviceApis::Commons::PlatformException,
314             "Couldn't move mail to folder: " << newFolder << ". [" <<
315             error << "]");
316     }
317 }
318
319 void Email::copyToFolder(const FolderType newFolder)
320 {
321     LOG_ENTER
322
323     copyToFolder(EmailConverter::toMailboxName(newFolder));
324
325     LOG_EXIT
326 }
327
328 void Email::copyToFolder(const string& newFolder)
329 {
330     LOG_ENTER
331
332     update();
333
334     int accountId = Messaging::getInstance().getEmailAccountId(getFromRef());
335
336     ScopedMail mail(EmailService::cloneMail(m_mail.Get()));
337     ScopedMailbox mailbox(
338         EmailService::createMailbox(accountId, newFolder.c_str())
339         );
340
341     int mailId = EmailService::addMailToMailbox(mail.Get(), mailbox.Get());
342     // TODO Is following check necessary?
343     if (0 == mailId) {
344         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Cloned mail didn't get new id.");
345     }
346
347     LOG_EXIT
348 }
349
350 void Email::remove()
351 {
352     EmailService::deleteMail(m_accountId, getIntId());
353 }
354
355 #if 0
356 void Email::create()
357 {
358     LOG_ENTER
359
360     EmailAccountInfo account = IMessaging::getInstance().getCurrentEmailAccount();
361     m_accountId = account.getIntId();
362     ScopedMail mail(EmailService::createMail(account));
363     ScopedMailbox mailbox(
364         EmailService::getMailboxByType(account.getIntId(),
365                                        EMF_MAILBOX_TYPE_DRAFT)
366         );
367     setId(convertId(EmailService::addMailToMailbox(mail.Get(), mailbox.Get())));
368     setFolderType(Api::Messaging::DRAFTBOX);
369     setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
370
371     LOG_EXIT
372 }
373 #endif
374
375 void Email::create()
376 {
377     LOG_ENTER
378     setFolderType(Api::Messaging::TEMP_FOLDER);
379     setMessageStatus(Api::Messaging::MESSAGE_STATUS_CREATED);
380     LOG_EXIT
381 }
382
383 void Email::create( Api::Messaging::EmailAccountInfo& account )
384 {
385         LOG_ENTER
386
387         m_accountId = account.getIntId();
388         MailSender::getInstance();
389         
390       LogDebug("account ID : " << m_accountId);
391         ScopedMail mail(EmailService::createMail(account));
392         setEmailAccount(account);       //save account
393         ScopedMailbox mailbox(EmailService::getMailboxByType(account.getIntId(), EMF_MAILBOX_TYPE_DRAFT));
394         setId(convertId(EmailService::addMailToMailbox(mail.Get(), mailbox.Get())));
395         setFolderType(Api::Messaging::DRAFTBOX);
396         setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
397             
398     LOG_EXIT
399 }
400
401 void Email::reload()
402 {
403     LOG_ENTER
404
405    //EmailAccountInfo account = Messaging::getInstance().getCurrentEmailAccount();
406     LogDebug("account ID :" << m_accountId);
407     m_mail.Reset(EmailService::readMail(m_accountId, getIntId()));
408
409     if (m_mail->head) { readHeader(); }
410     if (m_mail->body) { readBody(); }
411     if (m_mail->info) { readInfo(); }
412
413     m_mailbox.Reset(EmailService::getMailboxByMailId(m_accountId, getIntId()) );
414     setFolderType(EmailConverter::toFolderType(m_mailbox->mailbox_type));
415
416     LOG_EXIT
417 }
418
419 void Email::readHeader()
420 {
421     LOG_ENTER
422
423     Assert(m_mail && m_mail->head && "Header is NULL.");
424
425     if (m_mail->head->subject) {
426         setSubject(m_mail->head->subject);
427     }
428
429     if (m_mail->head->to) {
430         appendToRecipients(EmailUtils::stripAddressLine(m_mail->head->to));
431     }
432
433     if (m_mail->head->cc) {
434         appendCcRecipients(EmailUtils::stripAddressLine(m_mail->head->cc));
435     }
436
437     if (m_mail->head->bcc) {
438         appendBccRecipients(EmailUtils::stripAddressLine(m_mail->head->bcc));
439     }
440
441     time_t rawtime;
442     time(&rawtime);
443     struct tm tmpTime = *(localtime(&rawtime));
444     tmpTime.tm_year = m_mail->head->datetime.year;
445     tmpTime.tm_mon = m_mail->head->datetime.month;
446     tmpTime.tm_mday = m_mail->head->datetime.day;
447     tmpTime.tm_hour = m_mail->head->datetime.hour;
448     tmpTime.tm_min = m_mail->head->datetime.minute;
449     tmpTime.tm_sec = m_mail->head->datetime.second;
450     mktime(&tmpTime);
451     setDateTime(tmpTime);
452
453     if (m_mail->head->from) {
454         Recipients from;
455         from.setRecipients(m_mail->head->from);
456         setSourceAddress(from);
457         setSourceAddressValidity(true); //not needed to update in platform
458     }
459
460     LOG_EXIT
461 }
462
463 void Email::readBody() {
464         LOG_ENTER
465
466         Assert(m_mail && m_mail->body && "Body is NULL.");
467
468         if (m_mail->body->plain) {
469                 DPL::ScopedFClose file(::fopen(m_mail->body->plain, "r"));
470                 if (!file) {
471                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
472                                         "Cannot read body file: " << m_mail->body->plain);
473                 }
474                 fseek(file.Get(), 0, SEEK_END);
475                 long int size = ftell(file.Get());
476                 fseek(file.Get(), 0, SEEK_SET);
477                 DPL::ScopedPtr<char> data(new char[size + 1]);
478                 memset(data.Get(), 0, size + 1);
479                 fread(data.Get(), 1, size, file.Get());
480                 setBody(data.Get());
481         }
482
483         //html body.
484         if (m_mail->body->html) {
485                 DPL::ScopedFClose file(::fopen(m_mail->body->html, "r")); //auto close, scopedFClose
486                 if (!file) {
487                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
488                                         "Cannot read html body file: " << m_mail->body->html);
489                 }
490
491                 fseek(file.Get(), 0, SEEK_END);
492                 long int size = ftell(file.Get());
493                 fseek(file.Get(), 0, SEEK_SET);
494                 DPL::ScopedPtr<char> data(new char[size + 1]);
495                 memset(data.Get(), 0, size + 1);
496                 fread(data.Get(), 1, size, file.Get());
497                 setHtmlBody(data.Get()); //setHtmlBody declarate in Email Calss.
498         }
499         
500         if (m_mail->body->attachment && m_mail->body->attachment_num > 0) {
501                 LogDebug("reading attachments , attahcment count = " << m_mail->body->attachment_num);
502                 emf_attachment_info_t* attach = m_mail->body->attachment;
503                 for (int i = 0; i < m_mail->body->attachment_num; ++i) {
504                         if (!attach) {
505                                 LogDebug("throw platform exception");
506                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
507                                                 "Attachment list shorter than expected.");
508                         }
509                         
510                         try {
511                                 
512                                 LogError("id :" << attach->attachment_id << " name :" << attach->name << " download :" << attach->downloaded << " savefile :" << attach->savename );
513                                 
514                                 IAttachmentPtr tmpAtt(new Attachment(attach));
515                                 LogError(" create new attachment ");
516                                 if (tmpAtt)
517                                 {
518                                         //tmpAtt->setMessage(SharedFromThis());                 //set IMessagePtr
519                                         tmpAtt->rename(attach->name);
520                                         tmpAtt->setAttachmentID(attach->attachment_id);
521                                         tmpAtt->setDownloaded(attach->downloaded);
522                                         tmpAtt->setNth(i+1);
523                                         appendAttachment(tmpAtt);
524                                         LogError(" append complete");
525                                 }
526                                                                 
527                                 attach = attach->next;
528                 }
529                 catch (const WrtDeviceApis::Commons::Exception& ex) {
530                                 LogError("Error while trying to append attachment " <<
531                                         attach->savename << ": " << ex.DumpToString());
532                         }
533                 }
534         }
535
536         LOG_EXIT
537 }
538
539 void Email::readInfo()
540 {
541     LOG_ENTER
542
543     Assert(m_mail && m_mail->info && "Info is NULL.");
544
545     setReadStatus(m_mail->info->flags.seen == 1);
546
547     m_accountId = m_mail->info->account_id;
548
549     setPriority(
550         EmailConverter::toMessagePriority( m_mail->info->extra_flags.priority )
551         );
552     setSize(m_mail->info->rfc822_size);
553
554     LOG_EXIT
555 }
556
557 void Email::updateBody()
558 {
559     LOG_ENTER
560
561     if (isBodyValid()) { return; }
562
563     if (!m_mail) {
564         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
565     }
566
567     if (!m_mail->body) {
568         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Body is NULL.");
569     }
570     if (!m_mail->body->plain) {
571         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Body file is NULL.");
572     }
573
574     if (!m_mail->body->html) {
575         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Html Body file is NULL.");
576     }
577
578     if (!m_mail->info) {
579         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Info is NULL.");
580     }
581
582     //update plain body.
583     FILE* f = fopen(m_mail->body->plain, "w");
584     if (NULL != f) {
585         //fprintf(f, getBodyRef().c_str());
586         fwrite(getBodyRef().c_str(), strlen(getBodyRef().c_str()), 1, f);
587         fclose(f);
588     }
589     else
590     {
591                 LogDebug("Plain Body file is NULL.");
592     }
593
594     if (m_mail->body->html) {
595         //update html body
596         f = fopen(m_mail->body->html, "w");
597             if (NULL != f) {
598                 //fprintf(f, getHtmlBody().c_str());
599                   fwrite(getHtmlBody().c_str(), strlen(getHtmlBody().c_str()), 1, f);
600                 fclose(f);
601             } 
602     }
603     else
604     {
605                 LogDebug("Html Body file is NULL.");
606     }
607     
608     m_mail->info->body_downloaded = true;
609     setBodyValidity(true);
610
611     LOG_EXIT
612 }
613
614 void Email::updateSubject()
615 {
616     LOG_ENTER
617
618     if (isSubjectValid()) { return; }
619
620     LogDebug("update subject, msgId=" << getIdRef());
621
622     if (!m_mail) {
623         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
624     }
625
626     if (!m_mail->head) {
627         m_mail->head = EmailService::alloc<emf_mail_head_t>();
628     }
629
630     m_mail->head->subject = String::strdup(getSubjectRef());
631     setSubjectValidity(true);
632
633     LOG_EXIT
634 }
635
636 void Email::updateReadStatus()
637 {
638     LOG_ENTER
639
640     if (isReadStatusValid()) { return; }
641
642     LogDebug("update read, msgId=" << getIdRef());
643
644     if (!m_mail) {
645         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
646     }
647
648     if (!m_mail->info) {
649         EmailService::alloc<emf_mail_info_t>();
650     }
651
652     m_mail->info->flags.seen = isRead();
653     setReadStatusValidity(true);
654
655     LOG_EXIT
656 }
657
658 void Email::updateIsRead()
659 {
660     LOG_ENTER
661     if (isReadChangeStatusValid()) {
662         // do not update if not changed
663         return;
664     }
665
666     EmailService::updateSeenFlag(getAccountID(), getIntId(), isReadChangeStatus());
667     setisReadChangeStatusValidity(true);
668     LOG_EXIT
669 }
670
671 void Email::addMessageToDraft()
672 {
673     LOG_ENTER
674
675 #if 0
676         //check Message Status.
677     DPL::Mutex::ScopedLock mx(&m_updateMutex);
678
679     if (!m_mail) {
680         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
681     }
682
683     updateBody();
684     updateSubject();
685     updateRecipients();
686     updateFrom();
687     updatePriority();
688
689     int error = email_update_message(getIntId(), m_mail.Get()); 
690     LogDebug("add finished, mailId = " << error);               
691 #endif
692
693     if ( getUID() > 0 && m_accountId > 0)
694     {   //update
695
696         update();
697         
698     }
699     else
700     {
701                 Api::Messaging::EmailAccountInfo account = getEmailAccount();
702                 m_accountId = account.getIntId();       //set account ID
703                 MailSender::getInstance();
704                 
705                 LogDebug("account ID : " << m_accountId);       
706                 ScopedMail mail(EmailService::createMail(account));
707
708                 LogDebug("get mail" );
709                 emf_mail_t* ma = mail.Get();
710                 if (ma)
711                         LogDebug("UID : " << ma->info->uid);
712                 
713                 setEmailAccount(account);       //save account
714                 ScopedMailbox mailbox(EmailService::getMailboxByType(account.getIntId(), EMF_MAILBOX_TYPE_DRAFT));
715                 setId(convertId(EmailService::addMailToMailbox(mail.Get(), mailbox.Get())));
716
717                 reload();       //reload mail
718                 update(); //update message.
719
720                 LogDebug("Folder = " << EmailConverter::toFolderType(m_mailbox->mailbox_type));
721                 setFolderType(EmailConverter::toFolderType(m_mailbox->mailbox_type));
722                 setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
723                 
724                 LogDebug("Message ID : " << getUID());
725     }
726
727     LOG_EXIT
728 }
729
730 void Email::updateRecipients()
731 {
732     LOG_ENTER
733
734     if (getToValidity() && getCcValidity() && getBccValidity()) { return; }
735
736     if (!m_mail) {
737         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
738     }
739
740     if (!m_mail->head) {
741         m_mail->head = EmailService::alloc<emf_mail_head_t>();
742     }
743
744     if (!getToValidity()) {
745         std::string addressLine = EmailUtils::formatAddressLine(getToRecipients());
746         if (m_mail->head->to) {
747             free(m_mail->head->to);
748         }
749         m_mail->head->to = String::strdup(addressLine);
750         setToValidity(true);
751     }
752
753     if (!getCcValidity()) {
754         std::string addressLine = EmailUtils::formatAddressLine(getCcRecipients());
755         if (m_mail->head->cc) {
756             free(m_mail->head->cc);
757         }
758         m_mail->head->cc = String::strdup(addressLine);
759         setCcValidity(true);
760     }
761
762     if (!getBccValidity()) {
763         std::string addressLine = EmailUtils::formatAddressLine(
764                 getBccRecipients());
765         if (m_mail->head->bcc) {
766             free(m_mail->head->bcc);
767         }
768         m_mail->head->bcc = String::strdup(addressLine);
769         setBccValidity(true);
770     }
771
772     LOG_EXIT
773 }
774
775 void Email::updateFrom()
776 {
777     LOG_ENTER
778
779     if (getFromValidity()) { return; }
780
781     if (!m_mail) {
782         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
783     }
784
785     if (!m_mail->info) {
786         EmailService::alloc<emf_mail_info_t>();
787     }
788
789     m_mail->info->account_id = m_accountId;
790     // TODO Update m_mail->head->from as well
791
792     setFromValidity(true);
793
794     LOG_EXIT
795 }
796
797 void Email::updateAttachments()
798 {
799     LOG_ENTER
800
801     if (isAttachmentsValid()) { return; }
802
803     if (!m_mail) {
804         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail is NULL.");
805     }
806
807     emf_attachment_info_t* attachment = NULL;
808     Try {
809         LogDebug("update attachments, msgId=" << getIdRef());
810
811         if (!m_mail->body) {
812             m_mail->body = EmailService::alloc<emf_mail_body_t>();
813         } else {
814                 //clean attachment
815                 int i = m_mail->body->attachment_num;
816                 LogDebug("clean attachment, attachment count=" << i);
817                 attachment = m_mail->body->attachment;
818                 std::stringstream stream;
819                 
820                 while(attachment)
821                 {       
822                         LogDebug("delete file :" << attachment->name << " saved name :" << attachment->savename );
823                         int aId = attachment->attachment_id;
824                         char* mId = m_mail->head->mid;
825                         int n_mId = 0;
826                         stream << mId;
827                         stream >> n_mId;
828                         stream << aId;
829
830                         LogDebug("mID :"  << n_mId << " Attachment Id :" << aId );
831                         
832                         int error = email_delete_attachment(m_mailbox.Get(), n_mId, (const char*)(stream.str()).c_str());
833                         if (EMF_ERROR_NONE != error) {
834                             LogDebug("Error Num = " << error);
835                             ThrowMsg(WrtDeviceApis::Commons::PlatformException,
836                                      "Error while adding attachment. [" << error << "]");
837                         }
838                         attachment = attachment->next;
839                 }
840                 
841             m_mail->body->attachment_num = 0;
842             if (NULL != m_mail->body->attachment) {
843                 EmailService::freeAttachment(m_mail->body->attachment);
844                 m_mail->body->attachment = NULL;
845             }
846         }
847
848         std::size_t attachmentSize = getAttachmentsCount();
849         LogDebug("update attachments, attachmentSize=" << attachmentSize);
850         if (attachmentSize > 0) {
851             if (!m_mail->info) {
852                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail info is NULL.");
853             }
854
855             for (std::size_t i = 0; i < attachmentSize; ++i) {
856                 IAttachmentPtr att = getAttachment(i);
857                 if (!att) {
858                     continue;
859                 }
860
861                         //copy attachment file
862                         std::stringstream to_oss;
863                         to_oss << TEMP_FOLDER << "/" << att->getShortName();
864                         LogDebug("temp file=" << to_oss.str());
865                         
866                         std::stringstream cp_oss;
867                         cp_oss << COMMAND_NAME;
868                         cp_oss << " " << COMMAND_SWITCH_RECURSIVE;
869                         cp_oss << " \"" << att->getFullPath() << "\"";
870                         cp_oss << " \"" << to_oss.str() << "\"";
871
872                 attachment = EmailService::alloc<emf_attachment_info_t>();      //create attachment struct
873                 attachment->name = String::strdup(att->getShortName());
874                 //attachment->savename = String::strdup( att->getFullPath() );
875                 attachment->savename = String::strdup( to_oss.str().c_str() );
876                 
877                 attachment->next = NULL;
878                      attachment->downloaded = true;
879
880                         int result = system(cp_oss.str().c_str());                      
881                         if (-1 != result) {
882                             if (0 != WIFEXITED(result)) {
883                                 if (0 != WEXITSTATUS(result)) {
884                                     ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Command failed.");
885                                 }
886                             } else {
887                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
888                                          "Command terminated abnormally.");
889                             }
890                         } else {
891                             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Couldn't launch command.");
892                         }
893                                                                         
894                      LogDebug( "mailbox type = " << m_mailbox.Get()->mailbox_type);
895
896                 int error = email_add_attachment(m_mailbox.Get(),
897                                                  m_mail->info->uid,
898                                                  attachment);
899                 if (EMF_ERROR_NONE != error) {
900                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
901                              "Error while adding attachment. [" << error << "]");
902                 }
903                 else 
904                 {       
905                         LogDebug(" attachment id : " << attachment->attachment_id);                             
906                         //IMessagePtr msg = DPL::DynamicPointerCast<IMessage>(this);
907                         att->setDownloaded(true);
908                         att->setAttachmentID(attachment->attachment_id);
909                         att->setMessage(SharedFromThis());
910                         att->setNth(i+1);
911                 }
912
913                 EmailService::freeAttachment(attachment);
914             }
915
916             setAttachmentsValidity(true);
917         }
918     }
919     Catch(WrtDeviceApis::Commons::PlatformException) {
920         EmailService::freeAttachment(attachment);
921         throw;
922     }
923
924     LOG_EXIT
925 }
926
927 void Email::updatePriority()
928 {
929     LOG_ENTER
930
931     if (isPriorityValid()) { return; }
932
933     if (!m_mail) {
934         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Mail not allocated.");
935     }
936
937     if (!m_mail->info) {
938         m_mail->info = EmailService::alloc<emf_mail_info_t>();
939     }
940
941     m_mail->info->extra_flags.priority = EmailConverter::toMailPriority(
942             getPriority());
943     setPriorityValid(true);
944
945     LOG_EXIT
946 }
947
948 int Email::getIntId() const
949 {
950     return convertId(getIdRef());
951 }
952 }
953 }
954 }