82f139eff1ea19a06d6f974869ec35b21ee367c5
[framework/web/wrt-plugins-tizen.git] / src / Calendar / Calendar.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18
19 #include <calendar2.h>
20 #include <dpl/log/log.h>
21 #include <dpl/scoped_ptr.h>
22 #include "Calendar.h"
23 #include "CalendarManager.h"
24 #include "CalendarFilter.h"
25 #include "CalendarFilterValidator.h"
26 #include "CalendarUtility.h"
27 #include "OnEventsChanged.h"
28 #include "IEventWatchChanges.h"
29 #include "IEventClearWatch.h"
30 #include "EventId.h"
31 #include <IFilter.h>
32 #include <IFilterVisitor.h>
33 #include <sstream>
34 #include <algorithm>
35
36 using namespace WrtDeviceApis::Commons;
37
38 namespace DeviceAPI {
39 namespace Calendar {
40
41 Calendar::Calendar()
42 {
43 }
44
45 Calendar::~Calendar()
46 {
47 }
48
49 void Calendar::OnRequestReceived(const IEventAddEventPtr &event)
50 {
51     Try
52     {
53         if (!event->getEvent()) {
54             ThrowMsg(NullPointerException, "Item parameter is NULL.");
55         }
56         if (event->getEvent()->getIdIsSet()) {
57             LogWarning("Non-null item id.");
58             event->getEvent()->resetId();
59         }
60
61         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
62
63                 if(getIsUnified()) {
64                         LogDebug("Set the default calendar id for a unified calendar item.");
65                         event->getEvent()->setCalendarId(DEFAULT_EVENT_CALENDAR_BOOK_ID);
66                 } else {
67                         std::stringstream ss(getId());
68                         int calendarId;
69                         ss>>calendarId;
70                         event->getEvent()->setCalendarId(calendarId);
71                 }
72
73         eventWrapper->convertAbstractEventToPlatformEvent();
74
75         eventWrapper->saveEvent();
76
77         event->setResult(true);
78     }
79     Catch (Exception)
80     {
81         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
82         event->setResult(false);
83         event->setExceptionCode(ExceptionCodes::UnknownException);
84     }
85 }
86
87 void Calendar::OnRequestReceived(const IEventAddEventsPtr &event)
88 {
89     calendar_list_h listForAdd = NULL;
90
91     Try
92     {
93         if (event->getEvents()->empty()) {
94             ThrowMsg(NullPointerException, "Item array is empty.");
95         }
96
97         int ret, count = 0;
98         calendar_record_h record = NULL;
99         int* ids = NULL;
100
101         ret = calendar_list_create(&listForAdd);
102         if (CALENDAR_ERROR_NONE != ret) {
103             ThrowMsg(PlatformException, "Can't create a list: "<<ret);
104         }
105
106         for(unsigned int i=0; i<event->getEvents()->size(); i++) {
107                         CalendarEventPtr theItem = event->getEvents()->at(i);
108             if (theItem->getIdIsSet()) {
109                 LogWarning("Item has index: " << i << ". Resetting it.");
110                 theItem->resetId();
111             }
112             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(theItem, getType()));
113
114                         if(getIsUnified()) {
115                                 LogDebug("Set the default calendar id for a unified calendar item.");
116                                 theItem->setCalendarId(DEFAULT_EVENT_CALENDAR_BOOK_ID);
117                         } else {
118                                 std::stringstream ss(getId());
119                                 int calendarId;
120                                 ss>>calendarId;
121                                 theItem->setCalendarId(calendarId);
122                         }
123
124             eventWrapper->convertAbstractEventToPlatformEvent();
125
126             // Clone the record because the platform event will be freed by destructor.
127             record = NULL;
128             ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
129             if(CALENDAR_ERROR_NONE!=ret) {
130                 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
131             }
132
133             ret = calendar_list_add(listForAdd, record);
134             if (CALENDAR_ERROR_NONE != ret) {
135                 ThrowMsg(PlatformException, "Can't add the item to the list: "<<ret);
136             }
137         }
138
139         ret = calendar_db_insert_records(listForAdd, &ids, &count);
140         if (CALENDAR_ERROR_NONE != ret) {
141             ThrowMsg(PlatformException, "Can't insert the item list: "<<ret);
142         } else {
143             LogDebug("Add records requst done with count: "<<count);
144         }
145
146         for(int i=0; i<count; i++) {
147             event->getEvents()->at(i)->setId(ids[i]);
148         }
149
150                 if(ids) {
151                         free(ids);
152                 }
153
154         event->setResult(true);
155     }
156     Catch (Exception)
157     {
158         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
159         event->setResult(false);
160         event->setExceptionCode(ExceptionCodes::UnknownException);
161     }
162
163     if(listForAdd) {
164         calendar_list_destroy(listForAdd, true);
165     }
166 }
167
168 void Calendar::OnRequestReceived(const IEventUpdateEventPtr &event)
169 {
170     calendar_query_h query = NULL;
171     calendar_filter_h filter = NULL;
172
173     Try
174     {
175         if (!event->getEvent()) {
176             ThrowMsg(NullPointerException, "Item object is NULL.");
177         }
178
179         CalendarEventPtr theItem = event->getEvent();
180         if (!theItem->getIdIsSet()) {
181             ThrowMsg(InvalidArgumentException, "Item id is not set.");
182         }
183
184         int ret;
185
186         const char *dataType;
187         if(getType() == CalendarEvent::TASK_TYPE) {
188             dataType = _calendar_todo._uri;
189         } else {
190             dataType = _calendar_event._uri;
191         }
192
193         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(theItem, getType()));
194         eventWrapper->convertAbstractEventToPlatformEvent(true);
195
196         if ( event->getUpdateAllInstances() || 0>=theItem->getRecurrenceRule()->getFrequency()) {
197             // Platform detects the detached events and uptates all instances.
198             eventWrapper->saveEvent();
199         } else {
200             LogDebug("Update the exdate for a recurring parent event and add a new child event.");
201
202             // First update the parent event.
203             EventRecurrenceRulePtr rrule = theItem->getRecurrenceRule();
204             (*rrule->getExceptions()).push_back(theItem->getRecurrenceId());
205
206             std::string exdate = "";
207             for( unsigned int i=0; i<rrule->getExceptions()->size(); i++ ) {
208                 std::stringstream ss;
209                 ss<<rrule->getExceptions()->at(i);
210                 exdate.append(ss.str());
211                 if(i!=rrule->getExceptions()->size()-1) {
212                     exdate.append(",");
213                 }
214             }
215             ret = calendar_record_set_str(eventWrapper->getPlatformEvent(), _calendar_event.exdate, exdate.c_str());
216             if(ret!=CALENDAR_ERROR_NONE) {
217                 ThrowMsg(PlatformException, "Can't update the exdate: "<<ret);
218             } else {
219                 LogDebug("Set the exdate for the parent event: "<<exdate);
220             }
221
222             // Don't set the recurrence id for the parent event.
223             ret = calendar_record_set_str(eventWrapper->getPlatformEvent(), _calendar_event.recurrence_id, NULL);
224             if (CALENDAR_ERROR_NONE != ret) {
225                 ThrowMsg(PlatformException, "Can't set recurrence id.");
226             }
227
228             eventWrapper->saveEvent();
229
230             // Now add the detached child event.
231             EventRecurrenceRulePtr emptyRRule( new EventRecurrenceRule() );
232             // Detached event should not have rrule set.
233             theItem->setRecurrenceRule(emptyRRule);
234
235             theItem->setParentId(theItem->getId());
236
237             // Convert the modified child event.
238             eventWrapper->convertAbstractEventToPlatformEvent();
239
240             // Reset id for record insertion.
241             theItem->resetId();
242             eventWrapper->saveEvent();
243
244             theItem->setIsDetached(true);
245         }
246
247         event->setResult(true);
248     }
249     Catch (Exception)
250     {
251         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
252         event->setResult(false);
253         event->setExceptionCode(ExceptionCodes::UnknownException);
254     }
255
256     if(query) {
257         calendar_query_destroy(query);
258     }
259     if(filter) {
260         calendar_filter_destroy(filter);
261     }
262 }
263
264 void Calendar::OnRequestReceived(const IEventUpdateEventsPtr &event)
265 {
266     calendar_list_h listForUpdate = NULL;
267     calendar_list_h listForAdd = NULL;
268     calendar_query_h query =   NULL;
269     calendar_filter_h filter = NULL;
270
271     Try
272     {
273         if (event->getEvents()->empty()) {
274             ThrowMsg(NullPointerException, "Item array is empty.");
275         }
276
277         int ret, count = -1;
278         calendar_record_h record = NULL;
279
280         const char *dataType;
281         if(getType() == CalendarEvent::TASK_TYPE) {
282             dataType = _calendar_todo._uri;
283         } else {
284             dataType = _calendar_event._uri;
285         }
286
287         ret = calendar_list_create(&listForUpdate);
288         if (CALENDAR_ERROR_NONE != ret) {
289             ThrowMsg(PlatformException, "Can't create a list for update: "<<ret);
290         }
291         ret = calendar_list_create(&listForAdd);
292         if (CALENDAR_ERROR_NONE != ret) {
293             ThrowMsg(PlatformException, "Can't create a list for add: "<<ret);
294         }
295
296         for(unsigned int i=0; i<event->getEvents()->size(); i++) {
297             CalendarEventPtr thisEvent = event->getEvents()->at(i);
298             if (!thisEvent->getIdIsSet()) {
299                 ThrowMsg(InvalidArgumentException, "Item id is not set.");
300             }
301
302             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisEvent, getType()));
303             eventWrapper->convertAbstractEventToPlatformEvent(true);
304
305             if( true==thisEvent->getIsDetached() ) {
306                 // Treat the detached event same as the parent event.
307                 record = NULL;
308                 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
309                 if(CALENDAR_ERROR_NONE!=ret) {
310                     ThrowMsg(PlatformException, "Clonning failed: "<<ret);
311                 }
312
313                 ret = calendar_list_add(listForUpdate, record);
314                 if (CALENDAR_ERROR_NONE != ret) {
315                     ThrowMsg(PlatformException, "Can't add the detached item to the list: "<<ret);
316                     } else {
317                     LogDebug("Added the detached event to the update list: "<<thisEvent->getId());
318                     }
319             } else if (event->getUpdateAllInstances() || 0>=thisEvent->getRecurrenceRule()->getFrequency()) {
320                 // Platform detects the detached events and uptates all instances.
321                     record = NULL;
322                 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
323                     if(CALENDAR_ERROR_NONE!=ret) {
324                     ThrowMsg(PlatformException, "Clonning failed: "<<ret);
325                     }
326
327                     ret = calendar_list_add(listForUpdate, record);
328                     if (CALENDAR_ERROR_NONE != ret) {
329                     ThrowMsg(PlatformException, "Can't add the item to the list: "<<ret);
330                 }
331             } else {
332                 LogDebug("Update the exdate for a recurring parent event and add a new child event.");
333                 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(thisEvent, getType()));
334                 eventWrapperChild->convertAbstractEventToPlatformEvent(true);
335
336                 std::stringstream ss;
337                 ss<<thisEvent->getRecurrenceId();
338                 ret = calendar_record_set_str(eventWrapperChild->getPlatformEvent(), _calendar_event.recurrence_id, ss.str().c_str());
339                 if (CALENDAR_ERROR_NONE != ret) {
340                     ThrowMsg(PlatformException, "Cannot set event recurrence id: "<<ret);
341                 } else {
342                     LogDebug("Saved the rid for the child: "<<thisEvent->getRecurrenceId());
343                 }
344
345                 ret = calendar_record_set_int(eventWrapperChild->getPlatformEvent(), _calendar_event.original_event_id, thisEvent->getId());
346                 if (CALENDAR_ERROR_NONE != ret) {
347                     ThrowMsg(PlatformException, "Cannot set the parent id: "<<ret);
348                 }
349
350                 ret = calendar_record_set_int(eventWrapperChild->getPlatformEvent(), _calendar_event.freq, CALENDAR_RECURRENCE_NONE);
351                 if (CALENDAR_ERROR_NONE != ret) {
352                     ThrowMsg(PlatformException, "Cannot set the frequency: "<<ret);
353                 }
354
355                 record = NULL;
356                 ret = calendar_record_clone(eventWrapperChild->getPlatformEvent(), &record);
357                 if(CALENDAR_ERROR_NONE!=ret) {
358                     ThrowMsg(PlatformException, "Clonning the child event failed: "<<ret);
359                 }
360
361                 ret = calendar_list_add(listForAdd, record);
362                 if (CALENDAR_ERROR_NONE != ret) {
363                     ThrowMsg(PlatformException, "Can't add the item to the add list: "<<ret);
364                 }
365
366                 thisEvent->setIsDetached(true);
367
368                 // Now update the parent event.
369                 EventRecurrenceRulePtr rrule = thisEvent->getRecurrenceRule();
370                 (*rrule->getExceptions()).push_back(thisEvent->getRecurrenceId());
371
372                 std::string exdate = "";
373                 for( unsigned int j=0; j<rrule->getExceptions()->size(); j++ ) {
374                     std::stringstream ss;
375                     ss<<rrule->getExceptions()->at(j);
376                     exdate.append(ss.str());
377                     if(j!=rrule->getExceptions()->size()-1) {
378                         exdate.append(",");
379                     }
380                 }
381                 ret = calendar_record_set_str(eventWrapper->getPlatformEvent(), _calendar_event.exdate, exdate.c_str());
382                 if(ret!=CALENDAR_ERROR_NONE) {
383                     ThrowMsg(PlatformException, "Can't update the exdate: "<<ret);
384                 } else {
385                     LogDebug("Set the exdate for the parent event: "<<exdate);
386                 }
387
388                 record = NULL;
389                 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
390                 if(CALENDAR_ERROR_NONE!=ret) {
391                     ThrowMsg(PlatformException, "Clonning the child event failed: "<<ret);
392                 }
393
394                 ret = calendar_list_add(listForUpdate, record);
395                 if (CALENDAR_ERROR_NONE != ret) {
396                     ThrowMsg(PlatformException, "Can't add the item to the update list: "<<ret);
397                 }
398             }
399         }
400
401         // Perform the platform operations.
402         count = -1;
403         ret = calendar_list_get_count(listForAdd, &count);
404         if(CALENDAR_ERROR_NONE!=ret){
405             ThrowMsg(PlatformException, "Getting list count failed: "<<ret);
406         } else {
407             LogDebug("Final list count for add: "<<count);
408         }
409         if(count>0) {
410             ret = calendar_db_insert_records(listForAdd, NULL, NULL);
411             if (CALENDAR_ERROR_NONE != ret) {
412                 ThrowMsg(PlatformException, "Can't insert the item list: "<<ret);
413             } else {
414                 LogDebug("Add records requst done for update batch operation.");
415             }
416         }
417
418         count = -1;
419         ret = calendar_list_get_count(listForUpdate, &count);
420         if(CALENDAR_ERROR_NONE!=ret){
421             ThrowMsg(PlatformException, "Getting list count failed: "<<ret);
422         } else {
423             LogDebug("Final list count for update: "<<count);
424         }
425         if(count>0) {
426             ret = calendar_db_update_records(listForUpdate);
427             if (CALENDAR_ERROR_NONE != ret) {
428                 ThrowMsg(PlatformException, "Can't update the item list: "<<ret);
429             } else {
430                 LogDebug("Update records requst done for update batch operation.");
431             }
432         }
433
434         event->setResult(true);
435     }
436     Catch (Exception)
437     {
438         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
439         event->setResult(false);
440         event->setExceptionCode(ExceptionCodes::UnknownException);
441     }
442
443     if(listForAdd) {
444         calendar_list_destroy(listForAdd, true);
445     }
446     if(listForUpdate) {
447         calendar_list_destroy(listForUpdate, true);
448     }
449     if(query) {
450         calendar_query_destroy(query);
451     }
452     if(filter) {
453         calendar_filter_destroy(filter);
454     }
455 }
456
457 void Calendar::OnRequestReceived(const IEventDeleteEventPtr &event)
458 {
459     Try
460     {
461         if (!event->getEventId()) {
462             ThrowMsg(NullPointerException, "Item id is not set.");
463         }
464
465         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
466         event->getEventId()->setCalendarType(getType());
467         std::istringstream stream(event->getEventId()->getUId());
468         int id = -1;
469         stream>>id;
470         eventWrapper->getAbstractEvent()->setId(id);
471
472         std::stringstream ss(event->getEventId()->getRecurrenceId());
473         long long int rid;
474         ss>>rid;
475
476         LogDebug("id: " << id << ", rid: " << rid);
477
478         eventWrapper->loadEvent(id);
479
480         // recurrence id is reset while loading the platform event.
481         eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
482
483         eventWrapper->deleteEvent();
484         event->setResult(true);
485     }
486     Catch (NotFoundException)
487     {
488         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
489         event->setResult(false);
490         event->setExceptionCode(ExceptionCodes::NotFoundException);
491     }
492     Catch (Exception)
493     {
494         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
495         event->setResult(false);
496         event->setExceptionCode(ExceptionCodes::UnknownException);
497     }
498 }
499
500 void Calendar::OnRequestReceived(const IEventGetPtr &event)
501 {
502     Try
503     {
504         if (!event->getItemId()) {
505             ThrowMsg(NullPointerException, "Id parameter is NULL");
506         }
507
508         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
509         std::stringstream ss(event->getItemId()->getUId());
510         int id = -1;
511         ss>>id;
512
513         eventWrapper->loadEvent(id);
514
515         event->setItem(eventWrapper->getAbstractEvent());
516         event->setResult(true);
517     }
518     Catch (NotFoundException)
519     {
520         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
521         event->setResult(false);
522         event->setExceptionCode(ExceptionCodes::NotFoundException);
523     }
524     Catch (Exception)
525     {
526         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
527         event->setResult(false);
528         event->setExceptionCode(ExceptionCodes::UnknownException);
529     }
530 }
531
532 void Calendar::OnRequestReceived(const IEventDeleteEventsPtr &event)
533 {
534     calendar_list_h listForUpdate = NULL;
535     calendar_query_h query = NULL;
536     calendar_filter_h filter = NULL;
537
538     Try
539     {
540         if (event->getEventIds()->empty()) {
541             ThrowMsg(NullPointerException, "Item id array is empty.");
542         }
543
544         std::vector<int> listForDelete;
545         std::vector<int> listForDetached;
546         std::vector<int> listForDetachedParent;
547
548         int ret, id, count;
549         long long int rid;
550         calendar_record_h item, record;
551         const char *dataType = NULL;
552
553         ret = calendar_list_create(&listForUpdate);
554         if (CALENDAR_ERROR_NONE != ret) {
555             ThrowMsg(PlatformException, "Can't create a list for update: "<<ret);
556         }
557
558         for(unsigned int i=0; i<event->getEventIds()->size(); i++) {
559             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
560             event->getEventIds()->at(i)->setCalendarType(getType());
561
562             std::istringstream stream(event->getEventIds()->at(i)->getUId());
563             stream>>id;
564             eventWrapper->getAbstractEvent()->setId(id);
565
566             eventWrapper->loadEvent(id);
567             item = eventWrapper->getPlatformEvent();
568
569             std::stringstream ss(event->getEventIds()->at(i)->getRecurrenceId());
570             ss>>rid;
571             eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
572
573             // If the recurrenceId is set, delete the instance of recurring event only.
574             LogDebug("id to delete: " << id << ", rid: " << rid << ", type: " << getType());
575
576             dataType = NULL;
577             if(getType() == CalendarEvent::TASK_TYPE) {
578                 dataType = _calendar_todo._uri;
579             } else {
580                 dataType = _calendar_event._uri;
581             }
582
583             /* Platform detects the detached events and deletes them automatically.
584                         But if both parent and detached ids are added to the list, platform error is returned. */
585             if ( 0>=rid ) {
586                 listForDelete.push_back(id);
587             } else if (true==eventWrapper->getAbstractEvent()->getIsDetached() ) {
588                 listForDetached.push_back(id);
589
590                 int parentId;
591                 ret = calendar_record_get_int(eventWrapper->getPlatformEvent(), _calendar_event.original_event_id, &parentId);
592                 if (CALENDAR_ERROR_NONE != ret) {
593                     ThrowMsg(PlatformException, "Can't get the parent id: "<<ret);
594                 }
595                 listForDetachedParent.push_back(parentId);
596                 LogDebug("Added the detached event id: "<<id<<", parent id: "<<parentId);
597             } else {
598                 EventRecurrenceRulePtr rrule = eventWrapper->getAbstractEvent()->getRecurrenceRule();
599                 (*rrule->getExceptions()).push_back(rid);
600
601                 std::string exdate = "";
602                 for( unsigned int i=0; i<rrule->getExceptions()->size(); i++ ) {
603                     std::stringstream ss;
604                     ss<<rrule->getExceptions()->at(i);
605                     exdate.append(ss.str());
606                     if(i!=rrule->getExceptions()->size()-1) {
607                         exdate.append(",");
608                     }
609                 }
610                 ret = calendar_record_set_str(item, _calendar_event.exdate, exdate.c_str());
611                 if(ret!=CALENDAR_ERROR_NONE) {
612                     ThrowMsg(PlatformException, "Can't delete the instance: "<<ret);
613                 } else {
614                     LogDebug("Set the exdate: "<<exdate);
615                 }
616
617                 record = NULL;
618                 ret = calendar_record_clone(item, &record);
619                 if(CALENDAR_ERROR_NONE!=ret) {
620                     ThrowMsg(PlatformException, "Clonning failed: "<<ret);
621                 }
622
623                 ret = calendar_list_add(listForUpdate, record);
624                 if (CALENDAR_ERROR_NONE != ret) {
625                     ThrowMsg(PlatformException, "Can't add the item to the list: "<<ret);
626                 }
627                 LogDebug("Calendar item instance added for update.");
628             }
629         }
630
631         // Perform the platform operations.
632         // Uptate operatoin should be done first not to update records after deletion.
633         count = -1;
634         ret = calendar_list_get_count(listForUpdate, &count);
635         if(CALENDAR_ERROR_NONE!=ret){
636             LogWarning("Getting list count for update failed: "<<ret);
637         } else {
638             LogDebug("Final list count for update: "<<count);
639         }
640         if(count>0) {
641             ret = calendar_db_update_records(listForUpdate);
642             if (CALENDAR_ERROR_NONE != ret) {
643                 ThrowMsg(PlatformException, "Can't update the item list: "<<ret);
644             } else {
645                 LogDebug("Update records requst done for update batch operation.");
646             }
647         }
648
649         // Merge the detached event id list if the parent is not included in the delete list.
650         count = listForDetached.size();
651         LogDebug("Number of detached events: "<<count);
652         while(count--) {
653             std::vector<int>::iterator it;
654             it = std::find(listForDelete.begin(), listForDelete.end(), listForDetachedParent.at(count));
655             if(listForDelete.end()==it) {
656                 listForDelete.push_back(listForDetached.at(count));
657                 LogDebug("Add the detached event id to the delete list: "<<listForDetached.at(count));
658             } else {
659                 LogDebug("The parent id is already included to the delete list: "<<listForDetachedParent.at(count));
660             }
661         }
662         count = listForDelete.size();
663
664         LogDebug("Final list count for deletion: "<<count);
665         if(count>0) {
666             ret = calendar_db_delete_records(dataType, &listForDelete[0], count);
667             if (CALENDAR_ERROR_NONE != ret) {
668                 ThrowMsg(PlatformException, "Can't delete the records: "<<ret);
669             } else {
670                 LogDebug("Delete records requst done for delete batch operation.");
671             }
672         }
673
674         event->setResult(true);
675     }
676     Catch (NotFoundException)
677     {
678         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
679         event->setResult(false);
680         event->setExceptionCode(ExceptionCodes::NotFoundException);
681     }
682     Catch (Exception)
683     {
684         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
685         event->setResult(false);
686         event->setExceptionCode(ExceptionCodes::UnknownException);
687     }
688
689     if(query) {
690         calendar_query_destroy(query);
691     }
692     if(filter) {
693         calendar_filter_destroy(filter);
694     }
695     if(listForUpdate) {
696         calendar_list_destroy(listForUpdate, true);
697     }
698 }
699
700 void Calendar::OnRequestReceived(const IEventFindEventsPtr &event)
701 {
702     Try
703     {
704         CalendarFilterPtr calendarFilter( new CalendarFilter() );
705
706         calendarFilter->setType(getType());
707         LogDebug("Default filter created with type "<<getType());
708
709                 DeviceAPI::Tizen::IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<DeviceAPI::Tizen::IFilterVisitor>(calendarFilter);
710
711         int calendarId;
712         std::stringstream ss(getId());
713         ss>>calendarId;
714                 if (event->getGenericFilterIsSet()) {
715             DeviceAPI::Tizen::FilterPtr genericFilter = event->getGenericFilter();
716
717             DeviceAPI::Tizen::FilterValidatorPtr validator = CalendarFilterValidatorFactory::getCalendarFilterValidator();
718             bool success = genericFilter->validate(validator);
719             if(!success) {
720                 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
721             } else {
722                 LogDebug("Filter validation has passed.");
723             }
724
725                         genericFilter->travel(filterTraversal, 0);
726
727                         if(getIsUnified()) {
728                                 LogDebug("Set all calendars flag for a unified calendar.");
729                 calendarFilter->setCalendarId(CALENDAR_BOOK_FILTER_ALL, true);
730                         } else {
731                                 LogDebug("Set additional calendar id: "<<calendarId);
732                 calendarFilter->setCalendarId(calendarId, true);
733                         }
734                 } else {
735                         if(getIsUnified()) {
736                                 LogDebug("Set all calendars flag for a unified calendar.");
737                 calendarFilter->setCalendarId(CALENDAR_BOOK_FILTER_ALL, false);
738                         } else {
739                     LogDebug("Set calendar id: "<<calendarId);
740                 calendarFilter->setCalendarId(calendarId, false);
741                         }
742                 }
743
744                 if (event->getSortModesIsSet()) {
745                         calendarFilter->setSortMode(event->getSortModes());
746                 }
747
748                 calendarFilter->executeQuery();
749
750                 LogDebug("Return the query result after conversion.");
751
752         calendar_list_h resultList = calendarFilter->getResultRecordList();
753         int ret;
754         int count = calendarFilter->getResultRecordCount();
755         calendar_record_h currentRecord = NULL;
756
757         calendar_list_first(resultList);
758
759         while(count--) {
760             currentRecord = NULL;
761             ret = calendar_list_get_current_record_p(resultList, &currentRecord);
762             if ( CALENDAR_ERROR_NONE != ret ) {
763                 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
764             }
765
766             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(currentRecord, getType()));
767             event->addEvent(eventWrapper->convertPlatformEventToAbstractEvent());
768
769             calendar_list_next(resultList);
770         }
771         LogDebug("Length of found items: "<<event->getEvents()->size());
772
773                 // Handle the recurring event range filter corner case.
774                 int id = -1, parentCount = -1;
775                 bool found = false;
776         resultList = calendarFilter->getNormalInstanceResultRecordList();
777         count = calendarFilter->getNormalInstanceResultRecordCount();
778                 LogDebug("Number of found normal instances: "<<count);
779
780         currentRecord = NULL;
781         calendar_list_first(resultList);
782         while(count--) {
783             currentRecord = NULL;
784             ret = calendar_list_get_current_record_p(resultList, &currentRecord);
785             if ( CALENDAR_ERROR_NONE != ret ) {
786                 ThrowMsg(PlatformException, "Can't get a current record: "<<ret);
787             }
788
789                         id = -1;
790                         ret = calendar_record_get_int(currentRecord, _calendar_instance_normal_calendar_book.event_id, &id);
791                         if (CALENDAR_ERROR_NONE != ret) {
792                                 ThrowMsg(PlatformException, "Can't get the normal instance parent id: "<<ret);
793                         }
794
795                         // Skip if the parent event is already found.
796                         parentCount = event->getEvents()->size();
797                         found = false;
798                         while(parentCount--) {
799                                 if(id==event->getEvents()->at(parentCount)->getId()) {
800                                         LogDebug("Found the id: "<<id<<", thus skip this.");
801                                         found = true;
802                                         break;
803                                 }
804                         }
805
806                         if(false==found) {
807                                 LogDebug("Add the normal instance parent: "<<id);
808                     DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
809                                 eventWrapper->loadEvent(id);
810                     event->addEvent(eventWrapper->convertPlatformEventToAbstractEvent());
811                         }
812
813             calendar_list_next(resultList);
814         }
815         LogDebug("Length of found items including normal instances: "<<event->getEvents()->size());
816
817         resultList = calendarFilter->getAlldayInstanceResultRecordList();
818         count = calendarFilter->getAlldayInstanceResultRecordCount();
819                 LogDebug("Number of found allday instances: "<<count);
820
821         currentRecord = NULL;
822         calendar_list_first(resultList);
823         while(count--) {
824             currentRecord = NULL;
825             ret = calendar_list_get_current_record_p(resultList, &currentRecord);
826             if ( CALENDAR_ERROR_NONE != ret ) {
827                 ThrowMsg(PlatformException, "Can't get a current record: "<<ret);
828             }
829
830                         id = -1;
831                         ret = calendar_record_get_int(currentRecord, _calendar_instance_allday_calendar_book.event_id, &id);
832                         if (CALENDAR_ERROR_NONE != ret) {
833                                 ThrowMsg(PlatformException, "Can't get the allday instance parent id: "<<ret);
834                         }
835
836                         // Skip if the parent event is already found.
837                         parentCount = event->getEvents()->size();
838                         found = false;
839                         while(parentCount--) {
840                                 if(id==event->getEvents()->at(parentCount)->getId()) {
841                                         LogDebug("Found the id: "<<id<<", thus skip this.");
842                                         found = true;
843                                         break;
844                                 }
845                         }
846
847                         if(false==found) {
848                                 LogDebug("Add the allday instance parent: "<<id);
849                     DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
850                                 eventWrapper->loadEvent(id);
851                     event->addEvent(eventWrapper->convertPlatformEventToAbstractEvent());
852                         }
853
854             calendar_list_next(resultList);
855         }
856         LogDebug("Length of found items including allday instances: "<<event->getEvents()->size());
857
858         event->setResult(true);
859     }
860     Catch (InvalidArgumentException)
861     {
862         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
863         event->setResult(false);
864         event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
865     }
866     Catch (NotFoundException)
867     {
868         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
869         event->setResult(false);
870         event->setExceptionCode(ExceptionCodes::NotFoundException);
871     }
872     Catch (Exception)
873     {
874         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
875         event->setResult(false);
876         event->setExceptionCode(ExceptionCodes::UnknownException);
877     }
878 }
879
880 void Calendar::OnRequestReceived(const IEventCreateEventFromStringPtr &event)
881 {
882     Try
883     {
884         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
885         eventWrapper->createEventFromString(event->getEventString());
886         event->setEvent(eventWrapper->convertPlatformEventToAbstractEvent());
887         event->getEvent()->setCalendarType(getType());
888         event->setResult(true);
889     }
890     Catch(PlatformException)
891     {
892                 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
893         LogDebug("eventString: " + event->getEventString());
894         event->setResult(false);
895         event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
896     }
897     Catch (Exception)
898     {
899         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
900         LogDebug("eventString: " + event->getEventString());
901         event->setResult(false);
902         event->setExceptionCode(ExceptionCodes::UnknownException);
903     }
904 }
905
906 void Calendar::OnRequestReceived(const IEventExportEventToStringPtr &event)
907 {
908     Try
909     {
910         if (!event->getEvent()) {
911             ThrowMsg(NullPointerException, "event parameter is NULL");
912         }
913
914         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
915         event->getEvent()->setCalendarType(getType());
916         eventWrapper->convertAbstractEventToPlatformEvent();
917         event->setEventString(eventWrapper->exportEventToString());
918         event->setResult(true);
919     }
920     Catch (Exception)
921     {
922         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
923         event->setResult(false);
924         event->setExceptionCode(ExceptionCodes::UnknownException);
925     }
926 }
927
928 static void eventChangedCb(const char *view_uri, void *user_data)
929 {
930     LogDebug("Items change cb with view_uri: "<<view_uri);
931
932     OnEventsChangedPtr eventPtr(new OnEventsChanged());
933     calendar_list_h list = NULL;
934
935     Try
936     {
937         if (user_data == NULL) {
938             LogDebug("user_data is NULL.");
939                 return;
940         }
941
942         Calendar *thisCalendar = (Calendar*) user_data;
943
944         int ret, id, type, updatedVersion, calendarId, count = 0;
945
946
947                 if(thisCalendar->getIsUnified()) {
948                         LogDebug("Set the all calendar id for a unified calendar.");
949                         calendarId = CALENDAR_BOOK_FILTER_ALL;
950                 } else {
951                 std::stringstream ss(thisCalendar->getId());
952             ss>>calendarId;
953                 }
954
955         LogDebug("Getting items with calendar id: "<<calendarId<<", version: "<<thisCalendar->getLastChangedVersion()<<", type: "<<thisCalendar->getType());
956         if (CalendarEvent::TASK_TYPE==thisCalendar->getType()) {
957             ret = calendar_db_get_changes_by_version(_calendar_todo._uri, calendarId, thisCalendar->getLastChangedVersion(), &list, &updatedVersion);
958         } else {
959             ret = calendar_db_get_changes_by_version(_calendar_event._uri, calendarId, thisCalendar->getLastChangedVersion(), &list, &updatedVersion);
960         }
961         if( CALENDAR_ERROR_NONE!=ret ) {
962             ThrowMsg(PlatformException, "Can't get the updated item list: "<<ret);
963         }
964
965         ret = calendar_list_get_count(list, &count);
966         if( CALENDAR_ERROR_NONE!=ret ) {
967             ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
968         } else {
969             LogDebug("Item count: "<<count);
970         }
971
972         calendar_list_first(list);
973
974         calendar_record_h currentRecord = NULL;
975         while(count--)
976         {
977             currentRecord = NULL;
978             ret = calendar_list_get_current_record_p(list, &currentRecord);
979             if ( CALENDAR_ERROR_NONE != ret ) {
980                 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
981             }
982
983             ret = calendar_record_get_int(currentRecord, _calendar_updated_info.id ,&id);
984             if ( CALENDAR_ERROR_NONE != ret ) {
985                 ThrowMsg(PlatformException, "Can't get updated info id: "<<ret);
986             }
987
988             ret = calendar_record_get_int(currentRecord, _calendar_updated_info.modified_status ,&type);
989             if ( CALENDAR_ERROR_NONE != ret ) {
990                 ThrowMsg(PlatformException, "Can't get updated info modified status: "<<ret);
991             }
992
993             LogDebug("id "<<id<<", type "<<type);
994             if ( CALENDAR_EVENT_MODIFIED_STATUS_INSERTED==type ) {
995                 eventPtr->setStatus(OnEventsChanged::ON_ADD);
996             } else if ( CALENDAR_EVENT_MODIFIED_STATUS_UPDATED==type ) {
997                 eventPtr->setStatus(OnEventsChanged::ON_UPDATE);
998             } else if ( CALENDAR_EVENT_MODIFIED_STATUS_DELETED==type ) {
999                 eventPtr->setStatus(OnEventsChanged::ON_DELETE);
1000             } else {
1001                 LogWarning("Wrong change type.");
1002                 calendar_list_next(list);
1003                 continue;
1004             }
1005
1006             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisCalendar->getType()));
1007             Try {
1008                 eventWrapper->loadEvent(id);
1009             } Catch (NotFoundException){
1010                 LogDebug("Handling deleted event with index: "<<id);
1011             }
1012             eventPtr->addEvent(eventWrapper->getAbstractEvent());
1013
1014             calendar_list_next(list);
1015         }
1016
1017         ret = calendar_db_get_current_version(&updatedVersion);
1018         if( CALENDAR_ERROR_NONE!=ret ) {
1019             ThrowMsg(PlatformException, "Can't get new version: "<<ret);
1020         }
1021
1022         thisCalendar->setLastChangedVersion(updatedVersion);
1023         LogDebug("Last change fetch version: "<<thisCalendar->getLastChangedVersion());
1024
1025         eventPtr->setResult(true);
1026         eventPtr->setCalendarType(thisCalendar->getType());
1027
1028         if( eventPtr->getEventList()->size() > 0 ) {
1029             thisCalendar->m_changeEmitters.emit(eventPtr);
1030         } else {
1031             LogDebug("No actual changes. Skip signal emission.");
1032         }
1033     }
1034     Catch (Exception)
1035     {   
1036         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1037     }
1038
1039         if( list ) {
1040             calendar_list_destroy(list, true);
1041         }
1042 }
1043
1044 void Calendar::OnRequestReceived(const IEventWatchChangesPtr &event)
1045 {
1046     Try
1047     {
1048         // Subscribe the watch to the platform just once.
1049         int ret;
1050         if( m_changeEmitters.size()==0 )
1051         {
1052             const char *dataType;
1053             if(getType() == CalendarEvent::TASK_TYPE) {
1054                 dataType = _calendar_todo._uri;
1055             } else {
1056                 dataType = _calendar_event._uri;
1057             }
1058
1059             ret = calendar_db_add_changed_cb(dataType, eventChangedCb, this);
1060             if( CALENDAR_ERROR_NONE!=ret ) {
1061                 ThrowMsg(PlatformException, "Can't add db changed cb: "<<ret);
1062             } else {
1063                 // Save the last change fetch version to start watching.
1064                 int version;
1065                 ret = calendar_db_get_current_version(&version);
1066                 if( CALENDAR_ERROR_NONE!=ret ) {
1067                     ThrowMsg(PlatformException, "Can't get version: "<<ret);
1068                 } else {
1069                     setLastChangedVersion(version);
1070                     LogDebug("Last change fetch version: "<<getLastChangedVersion());
1071                 }
1072             }
1073         }
1074
1075         m_changeEmitters.attach(event->getEmitter());
1076         event->setWatchId(event->getEmitter()->getId());
1077         event->setResult(true);
1078     }
1079     Catch (Exception)
1080     {
1081         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1082         event->setResult(false);
1083         event->setExceptionCode(ExceptionCodes::UnknownException);
1084     }
1085 }
1086
1087 void Calendar::OnRequestReceived(const IEventClearWatchPtr &event)
1088 {
1089     Try
1090     {
1091         if( m_changeEmitters.detach(event->getWatchId()) ) {
1092             if( m_changeEmitters.size()==0 ) {
1093                 const char *dataType;
1094                 if(getType() == CalendarEvent::TASK_TYPE) {
1095                     dataType = _calendar_todo._uri;
1096                 } else {
1097                     dataType = _calendar_event._uri;
1098                 }
1099
1100                 if( CALENDAR_ERROR_NONE!=calendar_db_remove_changed_cb(dataType, eventChangedCb, this) ) {
1101                     ThrowMsg(PlatformException, "Can't remove change cb.");
1102                 } else {
1103                     LogDebug("Platform watch cleared successfully.");
1104                 }
1105             }
1106             event->setResult(true);
1107         } else {
1108             LogDebug("Wrong watch Id.");
1109             event->setResult(false);
1110         }
1111     }
1112     Catch (Exception)
1113     {
1114         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1115         event->setResult(false);
1116         event->setExceptionCode(ExceptionCodes::UnknownException);
1117     }
1118 }
1119
1120 void Calendar::OnRequestReceived(const IEventExpandEventRecurrencePtr &event)
1121 {
1122     const CalendarEventPtr calEvent = event->getEvent();
1123     const long long int startDate = event->getStartDate();
1124     const long long int endDate = event->getEndDate();
1125     bool isAllDay = calEvent->getIsAllDay();
1126
1127     calendar_query_h query =   NULL;
1128     calendar_filter_h filter = NULL;
1129     calendar_list_h list = NULL;
1130
1131     Try {
1132         if ( 0 >= calEvent->getRecurrenceRule()->getFrequency()) {
1133             ThrowMsg(InvalidArgumentException, "This is not a recurring event.");
1134         }
1135
1136         calendar_record_h currentRecord = NULL;
1137         int ret, currentRecordIndex, count=0;
1138
1139         calendar_time_s st, et;
1140                 if( true==isAllDay ) {
1141                         st.type = CALENDAR_TIME_LOCALTIME;
1142                         st.time.date = CalendarUtility::LLIToCalTime(calEvent->getTimeZone().c_str(), startDate).time.date;
1143
1144                         et.type = CALENDAR_TIME_LOCALTIME;
1145                         et.time.date = CalendarUtility::LLIToCalTime(calEvent->getTimeZone().c_str(), endDate).time.date;
1146                 } else {
1147         st.type = CALENDAR_TIME_UTIME;
1148         st.time.utime = startDate;
1149
1150         et.type = CALENDAR_TIME_UTIME;
1151         et.time.utime = endDate;
1152                 }
1153
1154         if( true==isAllDay ) {
1155             ret = calendar_query_create(_calendar_instance_allday_calendar_book._uri, &query);
1156         } else {
1157             ret = calendar_query_create(_calendar_instance_normal_calendar_book._uri, &query);
1158         }
1159         if( CALENDAR_ERROR_NONE!=ret ) {
1160             ThrowMsg(PlatformException, "Creating a query failed: "<<ret);
1161         }
1162
1163         if( true==isAllDay ) {
1164             ret = calendar_filter_create(_calendar_instance_allday_calendar_book._uri, &filter);
1165         } else {
1166             ret = calendar_filter_create(_calendar_instance_normal_calendar_book._uri, &filter);
1167         }
1168         if( CALENDAR_ERROR_NONE!=ret ) {
1169             ThrowMsg(PlatformException, "Creating a filter failed: "<<ret);
1170         }
1171
1172         if( true==isAllDay ) {
1173             ret = calendar_filter_add_caltime(filter, _calendar_instance_allday_calendar_book.start_time, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL, st);
1174         } else {
1175             ret = calendar_filter_add_caltime(filter, _calendar_instance_normal_calendar_book.start_time, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL, st);
1176         }
1177         if( CALENDAR_ERROR_NONE!=ret ) {
1178             ThrowMsg(PlatformException, "Adding a caltime filter failed: "<<ret);
1179         }
1180
1181         ret = calendar_filter_add_operator(filter, CALENDAR_FILTER_OPERATOR_AND);
1182         if( CALENDAR_ERROR_NONE!=ret ) {
1183             ThrowMsg(PlatformException, "Adding a filter operator failed: "<<ret);
1184         }
1185
1186         if( true==isAllDay ) {
1187             ret = calendar_filter_add_caltime(filter, _calendar_instance_allday_calendar_book.end_time, CALENDAR_MATCH_LESS_THAN_OR_EQUAL, et);
1188         } else {
1189             ret = calendar_filter_add_caltime(filter, _calendar_instance_normal_calendar_book.end_time, CALENDAR_MATCH_LESS_THAN_OR_EQUAL, et);
1190         }
1191         if( CALENDAR_ERROR_NONE!=ret ) {
1192             ThrowMsg(PlatformException, "Adding a caltime filter failed: "<<ret);
1193         }
1194
1195         ret = calendar_query_set_filter(query, filter);
1196         if( CALENDAR_ERROR_NONE!=ret ) {
1197             ThrowMsg(PlatformException, "Setting a filter: "<<ret);
1198         }
1199
1200         ret = calendar_db_get_records_with_query(query, 0, 0, &list);
1201         if( CALENDAR_ERROR_NONE!=ret ) {
1202             ThrowMsg(PlatformException, "Getting event instances failed: "<<ret);
1203         }
1204
1205         ret = calendar_list_get_count(list, &count);
1206         if( CALENDAR_ERROR_NONE!=ret ) {
1207             ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
1208         } else {
1209             LogDebug("Item count: "<<count<<", isAllDay: "<<isAllDay);
1210         }
1211
1212         calendar_list_first(list);
1213
1214         while(count--)
1215         {
1216             currentRecord = NULL;
1217             ret = calendar_list_get_current_record_p(list, &currentRecord);
1218             if ( CALENDAR_ERROR_NONE != ret ) {
1219                 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
1220             }
1221
1222             if( true==isAllDay ) {
1223                 ret = calendar_record_get_int(currentRecord, _calendar_instance_allday_calendar_book.event_id, &currentRecordIndex);
1224             } else {
1225             ret = calendar_record_get_int(currentRecord, _calendar_instance_normal_calendar_book.event_id, &currentRecordIndex);
1226             }
1227             if ( CALENDAR_ERROR_NONE != ret ) {
1228                 ThrowMsg(PlatformException, "Can't get current record id: "<<ret);
1229             }
1230
1231             if(currentRecordIndex==calEvent->getId()) {
1232                 DPL::ScopedPtr<EventWrapper> recurringEventWrapper(new EventWrapper(getType()));
1233                 recurringEventWrapper->loadEvent(calEvent->getId());
1234
1235                 // Set distintive attributes of each instance.
1236                 if( true==isAllDay ) {
1237                     ret = calendar_record_get_caltime(currentRecord, _calendar_instance_allday_calendar_book.start_time, &st);
1238
1239                                         recurringEventWrapper->getAbstractEvent()->setRecurrenceId(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), st));
1240                                         recurringEventWrapper->getAbstractEvent()->setStartTime(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), st));
1241                 } else {
1242                 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_normal_calendar_book.start_time, &st);
1243
1244                         recurringEventWrapper->getAbstractEvent()->setRecurrenceId(st.time.utime);
1245                         recurringEventWrapper->getAbstractEvent()->setStartTime(st.time.utime);
1246                 }
1247                 if ( CALENDAR_ERROR_NONE != ret ) {
1248                     ThrowMsg(PlatformException, "Can't get current record start time: "<<ret);
1249                 }
1250
1251                 if( true==isAllDay ) {
1252                     ret = calendar_record_get_caltime(currentRecord, _calendar_instance_allday_calendar_book.end_time, &et);
1253
1254                                         recurringEventWrapper->getAbstractEvent()->setEndTime(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), et));
1255                 } else {
1256                 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_normal_calendar_book.end_time, &et);
1257
1258                                         recurringEventWrapper->getAbstractEvent()->setEndTime(et.time.utime);
1259                 }
1260                 if ( CALENDAR_ERROR_NONE != ret ) {
1261                     ThrowMsg(PlatformException, "Can't get current record end time: "<<ret);
1262                 }
1263
1264                 LogDebug("Found a valid event instance with rid: "<<recurringEventWrapper->getAbstractEvent()->getRecurrenceId());
1265
1266                 event->addExpandedEvent(recurringEventWrapper->getAbstractEvent());
1267             }
1268
1269             calendar_list_next(list);
1270         }
1271         LogDebug("Length of expanded events from parent: "<<event->getExpandedEventList()->size());
1272
1273         if(query) {
1274             calendar_query_destroy(query);
1275             query = NULL;
1276         }
1277         if(filter) {
1278             calendar_filter_destroy(filter);
1279             filter = NULL;
1280         }
1281         if( list ) {
1282             calendar_list_destroy(list, true);
1283             list = NULL;
1284         }
1285
1286         // Consider the detached events also.
1287         currentRecord = NULL;
1288         int parentId = event->getEvent()->getId();
1289
1290         ret = calendar_query_create(_calendar_event._uri, &query);
1291         if( CALENDAR_ERROR_NONE!=ret ) {
1292             ThrowMsg(PlatformException, "Creating a query failed: "<<ret);
1293         }
1294
1295         ret = calendar_filter_create(_calendar_event._uri, &filter);
1296         if( CALENDAR_ERROR_NONE!=ret ) {
1297             ThrowMsg(PlatformException, "Creating a filter failed: "<<ret);
1298         }
1299
1300         ret = calendar_filter_add_int(filter, _calendar_event.original_event_id, CALENDAR_MATCH_EQUAL, parentId);
1301         if( CALENDAR_ERROR_NONE!=ret ) {
1302             ThrowMsg(PlatformException, "Adding an int filter failed: "<<ret);
1303         }
1304
1305         ret = calendar_query_set_filter(query, filter);
1306         if( CALENDAR_ERROR_NONE!=ret ) {
1307             ThrowMsg(PlatformException, "Setting a filter: "<<ret);
1308         }
1309
1310         ret = calendar_db_get_records_with_query(query, 0, 0, &list);
1311         if(CALENDAR_ERROR_NONE!=ret) {
1312             ThrowMsg(PlatformException, "Finding detached instances failed: "<<ret);
1313         }
1314
1315         ret = calendar_list_get_count(list, &count);
1316         if( CALENDAR_ERROR_NONE!=ret ) {
1317             ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
1318         } else {
1319             LogDebug("Item count: "<<count);
1320         }
1321
1322         calendar_list_first(list);
1323
1324         while(count--)
1325         {
1326             currentRecord = NULL;
1327             ret = calendar_list_get_current_record_p(list, &currentRecord);
1328             if ( CALENDAR_ERROR_NONE != ret ) {
1329                 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
1330             }
1331
1332             ret = calendar_record_get_int(currentRecord, _calendar_event.id, &currentRecordIndex);
1333             if ( CALENDAR_ERROR_NONE != ret ) {
1334                 ThrowMsg(PlatformException, "Can't get current record id: "<<ret);
1335             }
1336
1337             st = {CALENDAR_TIME_UTIME, {0}};
1338             ret = calendar_record_get_caltime(currentRecord, _calendar_event.start_time, &st);
1339             if ( CALENDAR_ERROR_NONE != ret ) {
1340                 ThrowMsg(PlatformException, "Can't get current record start time: "<<ret);
1341             }
1342
1343             et = {CALENDAR_TIME_UTIME, {0}};
1344             ret = calendar_record_get_caltime(currentRecord, _calendar_event.end_time, &et);
1345             if ( CALENDAR_ERROR_NONE != ret ) {
1346                 ThrowMsg(PlatformException, "Can't get current record end time: "<<ret);
1347             }
1348
1349             if (st.time.utime>=startDate && et.time.utime<=endDate) {
1350                 LogDebug("Found a valid detached event: "<<st.time.utime);
1351                 DPL::ScopedPtr<EventWrapper> detachedEventWrapper(new EventWrapper(getType()));
1352                 detachedEventWrapper->loadEvent(currentRecordIndex);
1353
1354                 // Set the same parent uid to each instances
1355                 detachedEventWrapper->getAbstractEvent()->setId(parentId);
1356                 // Set distintive attributes of each instance.
1357                 detachedEventWrapper->getAbstractEvent()->setRecurrenceId(st.time.utime);
1358                 detachedEventWrapper->getAbstractEvent()->setStartTime(st.time.utime);
1359                 detachedEventWrapper->getAbstractEvent()->setEndTime(et.time.utime);
1360
1361                 event->addExpandedEvent(detachedEventWrapper->getAbstractEvent());
1362             }
1363
1364             calendar_list_next(list);
1365         }
1366
1367         LogDebug("Length of total expanded events: "<<event->getExpandedEventList()->size());
1368
1369         event->setResult(true);
1370
1371         if(query) {
1372             calendar_query_destroy(query);
1373             query = NULL;
1374         }
1375         if(filter) {
1376             calendar_filter_destroy(filter);
1377             filter = NULL;
1378         }
1379         if( list ) {
1380             calendar_list_destroy(list, true);
1381             list = NULL;
1382         }
1383     }
1384     Catch (InvalidArgumentException)
1385     {
1386         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1387         event->setResult(false);
1388         event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
1389     }
1390     Catch (Exception)
1391     {
1392         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1393         event->setResult(false);
1394         event->setExceptionCode(ExceptionCodes::UnknownException);
1395     }
1396
1397     if(query) {
1398         calendar_query_destroy(query);
1399     }
1400     if(filter) {
1401         calendar_filter_destroy(filter);
1402     }
1403     if( list ) {
1404         calendar_list_destroy(list, true);
1405     }
1406 }
1407
1408 }
1409 }