2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <calendar2.h>
19 #include <dpl/scoped_ptr.h>
21 #include "CalendarManager.h"
22 #include "CalendarFilter.h"
23 #include "CalendarFilterValidator.h"
24 #include "CalendarUtility.h"
25 #include "OnEventsChanged.h"
26 #include "IEventWatchChanges.h"
27 #include "IEventClearWatch.h"
30 #include <IFilterVisitor.h>
35 using namespace WrtDeviceApis::Commons;
48 void Calendar::OnRequestReceived(const IEventAddEventPtr &event)
52 if (!event->getEvent()) {
53 ThrowMsg(NullPointerException, "Item parameter is NULL.");
55 if (event->getEvent()->getIdIsSet()) {
56 LoggerW("Non-null item id.");
57 event->getEvent()->resetId();
60 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
63 LoggerD("Set the default calendar id for a unified calendar item.");
64 event->getEvent()->setCalendarId(DEFAULT_EVENT_CALENDAR_BOOK_ID);
66 std::stringstream ss(getId());
69 event->getEvent()->setCalendarId(calendarId);
72 eventWrapper->convertAbstractEventToPlatformEvent();
74 eventWrapper->saveEvent();
76 event->setResult(true);
80 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
81 event->setResult(false);
82 event->setExceptionCode(ExceptionCodes::UnknownException);
86 void Calendar::OnRequestReceived(const IEventAddEventsPtr &event)
88 calendar_list_h listForAdd = NULL;
92 if (event->getEvents()->empty()) {
93 ThrowMsg(NullPointerException, "Item array is empty.");
97 calendar_record_h record = NULL;
100 ret = calendar_list_create(&listForAdd);
101 if (CALENDAR_ERROR_NONE != ret) {
102 ThrowMsg(PlatformException, "Can't create a list: "<<ret);
105 for(unsigned int i=0; i<event->getEvents()->size(); i++) {
106 CalendarEventPtr theItem = event->getEvents()->at(i);
107 if (theItem->getIdIsSet()) {
108 LoggerW("Item has index: " << i << ". Resetting it.");
111 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(theItem, getType()));
114 LoggerD("Set the default calendar id for a unified calendar item.");
115 theItem->setCalendarId(DEFAULT_EVENT_CALENDAR_BOOK_ID);
117 std::stringstream ss(getId());
120 theItem->setCalendarId(calendarId);
123 eventWrapper->convertAbstractEventToPlatformEvent();
125 // Clone the record because the platform event will be freed by destructor.
127 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
128 if(CALENDAR_ERROR_NONE!=ret) {
129 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
132 ret = calendar_list_add(listForAdd, record);
133 if (CALENDAR_ERROR_NONE != ret) {
134 ThrowMsg(PlatformException, "Can't add the item to the list: "<<ret);
138 ret = calendar_db_insert_records(listForAdd, &ids, &count);
139 if (CALENDAR_ERROR_NONE != ret) {
140 ThrowMsg(PlatformException, "Can't insert the item list: "<<ret);
142 LoggerD("Add records requst done with count: "<<count);
145 for(int i=0; i<count; i++) {
146 event->getEvents()->at(i)->setId(ids[i]);
153 event->setResult(true);
157 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
158 event->setResult(false);
159 event->setExceptionCode(ExceptionCodes::UnknownException);
163 calendar_list_destroy(listForAdd, true);
167 void Calendar::OnRequestReceived(const IEventUpdateEventPtr &event)
169 calendar_query_h query = NULL;
170 calendar_filter_h filter = NULL;
174 if (!event->getEvent()) {
175 ThrowMsg(NullPointerException, "Item object is NULL.");
178 CalendarEventPtr theItem = event->getEvent();
179 if (!theItem->getIdIsSet()) {
180 ThrowMsg(InvalidArgumentException, "Item id is not set.");
185 const char *dataType;
186 if(getType() == CalendarEvent::TASK_TYPE) {
187 dataType = _calendar_todo._uri;
189 dataType = _calendar_event._uri;
192 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(theItem, getType()));
193 eventWrapper->convertAbstractEventToPlatformEvent(true);
195 if ( event->getUpdateAllInstances() || 0>=theItem->getRecurrenceRule()->getFrequency() || UNDEFINED_TIME==theItem->getRecurrenceId()) {
196 // Platform detects the detached events and uptates all instances.
197 eventWrapper->saveEvent();
199 LoggerD("Update the exdate for a recurring parent event and add a new child event.");
201 // First update the parent event.
202 EventRecurrenceRulePtr rrule = theItem->getRecurrenceRule();
203 (*rrule->getExceptions()).push_back(theItem->getRecurrenceId());
205 std::string exdate = "";
206 for( unsigned int i=0; i<rrule->getExceptions()->size(); i++ ) {
207 std::stringstream ss;
208 ss<<rrule->getExceptions()->at(i);
209 exdate.append(ss.str());
210 if(i!=rrule->getExceptions()->size()-1) {
214 ret = calendar_record_set_str(eventWrapper->getPlatformEvent(), _calendar_event.exdate, exdate.c_str());
215 if(ret!=CALENDAR_ERROR_NONE) {
216 ThrowMsg(PlatformException, "Can't update the exdate: "<<ret);
218 LoggerD("Set the exdate for the parent event: "<<exdate);
221 // Don't set the recurrence id for the parent event.
222 ret = calendar_record_set_str(eventWrapper->getPlatformEvent(), _calendar_event.recurrence_id, NULL);
223 if (CALENDAR_ERROR_NONE != ret) {
224 ThrowMsg(PlatformException, "Can't set recurrence id.");
227 eventWrapper->saveEvent();
229 // Now add the detached child event.
230 EventRecurrenceRulePtr emptyRRule( new EventRecurrenceRule() );
231 // Detached event should not have rrule set.
232 theItem->setRecurrenceRule(emptyRRule);
234 theItem->setParentId(theItem->getId());
236 // Convert the modified child event.
237 eventWrapper->convertAbstractEventToPlatformEvent();
239 // Reset id for record insertion.
241 eventWrapper->saveEvent();
243 theItem->setIsDetached(true);
246 event->setResult(true);
250 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
251 event->setResult(false);
252 event->setExceptionCode(ExceptionCodes::UnknownException);
256 calendar_query_destroy(query);
259 calendar_filter_destroy(filter);
263 void Calendar::OnRequestReceived(const IEventUpdateEventsPtr &event)
265 calendar_list_h listForUpdate = NULL;
266 calendar_list_h listForAdd = NULL;
267 calendar_query_h query = NULL;
268 calendar_filter_h filter = NULL;
272 if (event->getEvents()->empty()) {
273 ThrowMsg(NullPointerException, "Item array is empty.");
277 calendar_record_h record = NULL;
279 const char *dataType;
280 if(getType() == CalendarEvent::TASK_TYPE) {
281 dataType = _calendar_todo._uri;
283 dataType = _calendar_event._uri;
286 ret = calendar_list_create(&listForUpdate);
287 if (CALENDAR_ERROR_NONE != ret) {
288 ThrowMsg(PlatformException, "Can't create a list for update: "<<ret);
290 ret = calendar_list_create(&listForAdd);
291 if (CALENDAR_ERROR_NONE != ret) {
292 ThrowMsg(PlatformException, "Can't create a list for add: "<<ret);
295 for(unsigned int i=0; i<event->getEvents()->size(); i++) {
296 CalendarEventPtr thisEvent = event->getEvents()->at(i);
297 if (!thisEvent->getIdIsSet()) {
298 ThrowMsg(InvalidArgumentException, "Item id is not set.");
301 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisEvent, getType()));
302 eventWrapper->convertAbstractEventToPlatformEvent(true);
304 if( true==thisEvent->getIsDetached() ) {
305 // Treat the detached event same as the parent event.
307 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
308 if(CALENDAR_ERROR_NONE!=ret) {
309 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
312 ret = calendar_list_add(listForUpdate, record);
313 if (CALENDAR_ERROR_NONE != ret) {
314 ThrowMsg(PlatformException, "Can't add the detached item to the list: "<<ret);
316 LoggerD("Added the detached event to the update list: "<<thisEvent->getId());
318 } else if (event->getUpdateAllInstances() || 0>=thisEvent->getRecurrenceRule()->getFrequency() || UNDEFINED_TIME==thisEvent->getRecurrenceId()) {
319 // Platform detects the detached events and uptates all instances.
321 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
322 if(CALENDAR_ERROR_NONE!=ret) {
323 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
326 ret = calendar_list_add(listForUpdate, record);
327 if (CALENDAR_ERROR_NONE != ret) {
328 ThrowMsg(PlatformException, "Can't add the item to the list: "<<ret);
331 LoggerD("Update the exdate for a recurring parent event and add a new child event.");
332 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(thisEvent, getType()));
333 eventWrapperChild->convertAbstractEventToPlatformEvent(true);
335 std::stringstream ss;
336 ss<<thisEvent->getRecurrenceId();
337 ret = calendar_record_set_str(eventWrapperChild->getPlatformEvent(), _calendar_event.recurrence_id, ss.str().c_str());
338 if (CALENDAR_ERROR_NONE != ret) {
339 ThrowMsg(PlatformException, "Cannot set event recurrence id: "<<ret);
341 LoggerD("Saved the rid for the child: "<<thisEvent->getRecurrenceId());
344 ret = calendar_record_set_int(eventWrapperChild->getPlatformEvent(), _calendar_event.original_event_id, thisEvent->getId());
345 if (CALENDAR_ERROR_NONE != ret) {
346 ThrowMsg(PlatformException, "Cannot set the parent id: "<<ret);
349 ret = calendar_record_set_int(eventWrapperChild->getPlatformEvent(), _calendar_event.freq, CALENDAR_RECURRENCE_NONE);
350 if (CALENDAR_ERROR_NONE != ret) {
351 ThrowMsg(PlatformException, "Cannot set the frequency: "<<ret);
355 ret = calendar_record_clone(eventWrapperChild->getPlatformEvent(), &record);
356 if(CALENDAR_ERROR_NONE!=ret) {
357 ThrowMsg(PlatformException, "Clonning the child event failed: "<<ret);
360 ret = calendar_list_add(listForAdd, record);
361 if (CALENDAR_ERROR_NONE != ret) {
362 ThrowMsg(PlatformException, "Can't add the item to the add list: "<<ret);
365 thisEvent->setIsDetached(true);
367 // Now update the parent event.
368 EventRecurrenceRulePtr rrule = thisEvent->getRecurrenceRule();
369 (*rrule->getExceptions()).push_back(thisEvent->getRecurrenceId());
371 std::string exdate = "";
372 for( unsigned int j=0; j<rrule->getExceptions()->size(); j++ ) {
373 std::stringstream ss;
374 ss<<rrule->getExceptions()->at(j);
375 exdate.append(ss.str());
376 if(j!=rrule->getExceptions()->size()-1) {
380 ret = calendar_record_set_str(eventWrapper->getPlatformEvent(), _calendar_event.exdate, exdate.c_str());
381 if(ret!=CALENDAR_ERROR_NONE) {
382 ThrowMsg(PlatformException, "Can't update the exdate: "<<ret);
384 LoggerD("Set the exdate for the parent event: "<<exdate);
388 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
389 if(CALENDAR_ERROR_NONE!=ret) {
390 ThrowMsg(PlatformException, "Clonning the child event failed: "<<ret);
393 ret = calendar_list_add(listForUpdate, record);
394 if (CALENDAR_ERROR_NONE != ret) {
395 ThrowMsg(PlatformException, "Can't add the item to the update list: "<<ret);
400 // Perform the platform operations.
402 ret = calendar_list_get_count(listForAdd, &count);
403 if(CALENDAR_ERROR_NONE!=ret){
404 ThrowMsg(PlatformException, "Getting list count failed: "<<ret);
406 LoggerD("Final list count for add: "<<count);
409 ret = calendar_db_insert_records(listForAdd, NULL, NULL);
410 if (CALENDAR_ERROR_NONE != ret) {
411 ThrowMsg(PlatformException, "Can't insert the item list: "<<ret);
413 LoggerD("Add records requst done for update batch operation.");
418 ret = calendar_list_get_count(listForUpdate, &count);
419 if(CALENDAR_ERROR_NONE!=ret){
420 ThrowMsg(PlatformException, "Getting list count failed: "<<ret);
422 LoggerD("Final list count for update: "<<count);
425 ret = calendar_db_update_records(listForUpdate);
426 if (CALENDAR_ERROR_NONE != ret) {
427 ThrowMsg(PlatformException, "Can't update the item list: "<<ret);
429 LoggerD("Update records requst done for update batch operation.");
433 event->setResult(true);
437 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
438 event->setResult(false);
439 event->setExceptionCode(ExceptionCodes::UnknownException);
443 calendar_list_destroy(listForAdd, true);
446 calendar_list_destroy(listForUpdate, true);
449 calendar_query_destroy(query);
452 calendar_filter_destroy(filter);
456 void Calendar::OnRequestReceived(const IEventDeleteEventPtr &event)
460 if (!event->getEventId()) {
461 ThrowMsg(NullPointerException, "Item id is not set.");
464 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
465 event->getEventId()->setCalendarType(getType());
466 std::istringstream stream(event->getEventId()->getUId());
469 eventWrapper->getAbstractEvent()->setId(id);
471 std::stringstream ss(event->getEventId()->getRecurrenceId());
475 LoggerD("id: " << id << ", rid: " << rid);
477 eventWrapper->loadEvent(id);
479 // recurrence id is reset while loading the platform event.
480 eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
482 eventWrapper->deleteEvent();
483 event->setResult(true);
485 Catch (NotFoundException)
487 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
488 event->setResult(false);
489 event->setExceptionCode(ExceptionCodes::NotFoundException);
493 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
494 event->setResult(false);
495 event->setExceptionCode(ExceptionCodes::UnknownException);
499 void Calendar::OnRequestReceived(const IEventGetPtr &event)
503 if (!event->getItemId()) {
504 ThrowMsg(NullPointerException, "Id parameter is NULL");
507 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
508 std::stringstream ss(event->getItemId()->getUId());
512 eventWrapper->loadEvent(id);
514 event->setItem(eventWrapper->getAbstractEvent());
515 event->setResult(true);
517 Catch (NotFoundException)
519 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
520 event->setResult(false);
521 event->setExceptionCode(ExceptionCodes::NotFoundException);
525 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
526 event->setResult(false);
527 event->setExceptionCode(ExceptionCodes::UnknownException);
531 void Calendar::OnRequestReceived(const IEventDeleteEventsPtr &event)
533 calendar_list_h listForUpdate = NULL;
534 calendar_query_h query = NULL;
535 calendar_filter_h filter = NULL;
539 if (event->getEventIds()->empty()) {
540 ThrowMsg(NullPointerException, "Item id array is empty.");
543 std::vector<int> listForDelete;
544 std::vector<int> listForDetached;
545 std::vector<int> listForDetachedParent;
549 calendar_record_h item, record;
550 const char *dataType = NULL;
552 ret = calendar_list_create(&listForUpdate);
553 if (CALENDAR_ERROR_NONE != ret) {
554 ThrowMsg(PlatformException, "Can't create a list for update: "<<ret);
557 for(unsigned int i=0; i<event->getEventIds()->size(); i++) {
558 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
559 event->getEventIds()->at(i)->setCalendarType(getType());
561 std::istringstream stream(event->getEventIds()->at(i)->getUId());
563 eventWrapper->getAbstractEvent()->setId(id);
565 eventWrapper->loadEvent(id);
566 item = eventWrapper->getPlatformEvent();
568 std::stringstream ss(event->getEventIds()->at(i)->getRecurrenceId());
570 eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
572 // If the recurrenceId is set, delete the instance of recurring event only.
573 LoggerD("id to delete: " << id << ", rid: " << rid << ", type: " << getType());
576 if(getType() == CalendarEvent::TASK_TYPE) {
577 dataType = _calendar_todo._uri;
579 dataType = _calendar_event._uri;
582 /* Platform detects the detached events and deletes them automatically.
583 But if both parent and detached ids are added to the list, platform error is returned. */
585 listForDelete.push_back(id);
586 } else if (true==eventWrapper->getAbstractEvent()->getIsDetached() ) {
587 listForDetached.push_back(id);
590 ret = calendar_record_get_int(eventWrapper->getPlatformEvent(), _calendar_event.original_event_id, &parentId);
591 if (CALENDAR_ERROR_NONE != ret) {
592 ThrowMsg(PlatformException, "Can't get the parent id: "<<ret);
594 listForDetachedParent.push_back(parentId);
595 LoggerD("Added the detached event id: "<<id<<", parent id: "<<parentId);
597 EventRecurrenceRulePtr rrule = eventWrapper->getAbstractEvent()->getRecurrenceRule();
598 (*rrule->getExceptions()).push_back(rid);
600 std::string exdate = "";
601 for( unsigned int i=0; i<rrule->getExceptions()->size(); i++ ) {
602 std::stringstream ss;
603 ss<<rrule->getExceptions()->at(i);
604 exdate.append(ss.str());
605 if(i!=rrule->getExceptions()->size()-1) {
609 ret = calendar_record_set_str(item, _calendar_event.exdate, exdate.c_str());
610 if(ret!=CALENDAR_ERROR_NONE) {
611 ThrowMsg(PlatformException, "Can't delete the instance: "<<ret);
613 LoggerD("Set the exdate: "<<exdate);
617 ret = calendar_record_clone(item, &record);
618 if(CALENDAR_ERROR_NONE!=ret) {
619 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
622 ret = calendar_list_add(listForUpdate, record);
623 if (CALENDAR_ERROR_NONE != ret) {
624 ThrowMsg(PlatformException, "Can't add the item to the list: "<<ret);
626 LoggerD("Calendar item instance added for update.");
630 // Perform the platform operations.
631 // Uptate operatoin should be done first not to update records after deletion.
633 ret = calendar_list_get_count(listForUpdate, &count);
634 if(CALENDAR_ERROR_NONE!=ret){
635 LoggerW("Getting list count for update failed: "<<ret);
637 LoggerD("Final list count for update: "<<count);
640 ret = calendar_db_update_records(listForUpdate);
641 if (CALENDAR_ERROR_NONE != ret) {
642 ThrowMsg(PlatformException, "Can't update the item list: "<<ret);
644 LoggerD("Update records requst done for update batch operation.");
648 // Merge the detached event id list if the parent is not included in the delete list.
649 count = listForDetached.size();
650 LoggerD("Number of detached events: "<<count);
652 std::vector<int>::iterator it;
653 it = std::find(listForDelete.begin(), listForDelete.end(), listForDetachedParent.at(count));
654 if(listForDelete.end()==it) {
655 listForDelete.push_back(listForDetached.at(count));
656 LoggerD("Add the detached event id to the delete list: "<<listForDetached.at(count));
658 LoggerD("The parent id is already included to the delete list: "<<listForDetachedParent.at(count));
661 count = listForDelete.size();
663 LoggerD("Final list count for deletion: "<<count);
665 ret = calendar_db_delete_records(dataType, &listForDelete[0], count);
666 if (CALENDAR_ERROR_NONE != ret) {
667 ThrowMsg(PlatformException, "Can't delete the records: "<<ret);
669 LoggerD("Delete records requst done for delete batch operation.");
673 event->setResult(true);
675 Catch (NotFoundException)
677 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
678 event->setResult(false);
679 event->setExceptionCode(ExceptionCodes::NotFoundException);
683 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
684 event->setResult(false);
685 event->setExceptionCode(ExceptionCodes::UnknownException);
689 calendar_query_destroy(query);
692 calendar_filter_destroy(filter);
695 calendar_list_destroy(listForUpdate, true);
699 void Calendar::OnRequestReceived(const IEventFindEventsPtr &event)
703 CalendarFilterPtr calendarFilter( new CalendarFilter() );
705 calendarFilter->setType(getType());
706 LoggerD("Default filter created with type "<<getType());
708 DeviceAPI::Tizen::IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<DeviceAPI::Tizen::IFilterVisitor>(calendarFilter);
711 std::stringstream ss(getId());
713 if (event->getGenericFilterIsSet()) {
714 DeviceAPI::Tizen::FilterPtr genericFilter = event->getGenericFilter();
716 DeviceAPI::Tizen::FilterValidatorPtr validator = CalendarFilterValidatorFactory::getCalendarFilterValidator();
717 bool success = genericFilter->validate(validator);
719 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
721 LoggerD("Filter validation has passed.");
724 genericFilter->travel(filterTraversal, 0);
727 LoggerD("Set all calendars flag for a unified calendar.");
728 calendarFilter->setCalendarId(CALENDAR_BOOK_FILTER_ALL, true);
730 LoggerD("Set additional calendar id: "<<calendarId);
731 calendarFilter->setCalendarId(calendarId, true);
735 LoggerD("Set all calendars flag for a unified calendar.");
736 calendarFilter->setCalendarId(CALENDAR_BOOK_FILTER_ALL, false);
738 LoggerD("Set calendar id: "<<calendarId);
739 calendarFilter->setCalendarId(calendarId, false);
743 if (event->getSortModesIsSet()) {
744 calendarFilter->setSortMode(event->getSortModes());
747 calendarFilter->executeQuery();
749 LoggerD("Return the query result after conversion.");
751 calendar_list_h resultList = calendarFilter->getResultRecordList();
753 int count = calendarFilter->getResultRecordCount();
754 calendar_record_h currentRecord = NULL;
756 calendar_list_first(resultList);
759 currentRecord = NULL;
760 ret = calendar_list_get_current_record_p(resultList, ¤tRecord);
761 if ( CALENDAR_ERROR_NONE != ret ) {
762 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
765 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(currentRecord, getType()));
766 event->addEvent(eventWrapper->convertPlatformEventToAbstractEvent());
768 calendar_list_next(resultList);
770 LoggerD("Length of found items: "<<event->getEvents()->size());
772 // Handle the recurring event range filter corner case.
773 int id = -1, parentCount = -1;
775 resultList = calendarFilter->getNormalInstanceResultRecordList();
776 count = calendarFilter->getNormalInstanceResultRecordCount();
777 LoggerD("Number of found normal instances: "<<count);
779 currentRecord = NULL;
780 calendar_list_first(resultList);
782 currentRecord = NULL;
783 ret = calendar_list_get_current_record_p(resultList, ¤tRecord);
784 if ( CALENDAR_ERROR_NONE != ret ) {
785 ThrowMsg(PlatformException, "Can't get a current record: "<<ret);
789 ret = calendar_record_get_int(currentRecord, _calendar_instance_normal_calendar_book.event_id, &id);
790 if (CALENDAR_ERROR_NONE != ret) {
791 ThrowMsg(PlatformException, "Can't get the normal instance parent id: "<<ret);
794 // Skip if the parent event is already found.
795 parentCount = event->getEvents()->size();
797 while(parentCount--) {
798 if(id==event->getEvents()->at(parentCount)->getId()) {
799 LoggerD("Found the id: "<<id<<", thus skip this.");
806 LoggerD("Add the normal instance parent: "<<id);
807 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
808 eventWrapper->loadEvent(id);
809 event->addEvent(eventWrapper->convertPlatformEventToAbstractEvent());
812 calendar_list_next(resultList);
814 LoggerD("Length of found items including normal instances: "<<event->getEvents()->size());
816 resultList = calendarFilter->getAlldayInstanceResultRecordList();
817 count = calendarFilter->getAlldayInstanceResultRecordCount();
818 LoggerD("Number of found allday instances: "<<count);
820 currentRecord = NULL;
821 calendar_list_first(resultList);
823 currentRecord = NULL;
824 ret = calendar_list_get_current_record_p(resultList, ¤tRecord);
825 if ( CALENDAR_ERROR_NONE != ret ) {
826 ThrowMsg(PlatformException, "Can't get a current record: "<<ret);
830 ret = calendar_record_get_int(currentRecord, _calendar_instance_allday_calendar_book.event_id, &id);
831 if (CALENDAR_ERROR_NONE != ret) {
832 ThrowMsg(PlatformException, "Can't get the allday instance parent id: "<<ret);
835 // Skip if the parent event is already found.
836 parentCount = event->getEvents()->size();
838 while(parentCount--) {
839 if(id==event->getEvents()->at(parentCount)->getId()) {
840 LoggerD("Found the id: "<<id<<", thus skip this.");
847 LoggerD("Add the allday instance parent: "<<id);
848 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
849 eventWrapper->loadEvent(id);
850 event->addEvent(eventWrapper->convertPlatformEventToAbstractEvent());
853 calendar_list_next(resultList);
855 LoggerD("Length of found items including allday instances: "<<event->getEvents()->size());
857 event->setResult(true);
859 Catch (InvalidArgumentException)
861 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
862 event->setResult(false);
863 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
865 Catch (NotFoundException)
867 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
868 event->setResult(false);
869 event->setExceptionCode(ExceptionCodes::NotFoundException);
873 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
874 event->setResult(false);
875 event->setExceptionCode(ExceptionCodes::UnknownException);
879 void Calendar::OnRequestReceived(const IEventCreateEventFromStringPtr &event)
883 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
884 eventWrapper->createEventFromString(event->getEventString());
885 event->setEvent(eventWrapper->convertPlatformEventToAbstractEvent());
886 event->getEvent()->setCalendarType(getType());
887 event->setResult(true);
889 Catch(PlatformException)
891 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
892 LoggerD("eventString: " + event->getEventString());
893 event->setResult(false);
894 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
898 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
899 LoggerD("eventString: " + event->getEventString());
900 event->setResult(false);
901 event->setExceptionCode(ExceptionCodes::UnknownException);
905 void Calendar::OnRequestReceived(const IEventExportEventToStringPtr &event)
909 if (!event->getEvent()) {
910 ThrowMsg(NullPointerException, "event parameter is NULL");
913 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
914 event->getEvent()->setCalendarType(getType());
915 eventWrapper->convertAbstractEventToPlatformEvent();
916 event->setEventString(eventWrapper->exportEventToString());
917 event->setResult(true);
921 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
922 event->setResult(false);
923 event->setExceptionCode(ExceptionCodes::UnknownException);
927 static void eventChangedCb(const char *view_uri, void *user_data)
929 LoggerD("Items change cb with view_uri: "<<view_uri);
931 OnEventsChangedPtr eventPtr(new OnEventsChanged());
932 calendar_list_h list = NULL;
936 if (user_data == NULL) {
937 LoggerD("user_data is NULL.");
941 Calendar *thisCalendar = (Calendar*) user_data;
943 int ret, id, type, updatedVersion, calendarId, count = 0;
946 if(thisCalendar->getIsUnified()) {
947 LoggerD("Set the all calendar id for a unified calendar.");
948 calendarId = CALENDAR_BOOK_FILTER_ALL;
950 std::stringstream ss(thisCalendar->getId());
954 LoggerD("Getting items with calendar id: "<<calendarId<<", version: "<<thisCalendar->getLastChangedVersion()<<", type: "<<thisCalendar->getType());
955 if (CalendarEvent::TASK_TYPE==thisCalendar->getType()) {
956 ret = calendar_db_get_changes_by_version(_calendar_todo._uri, calendarId, thisCalendar->getLastChangedVersion(), &list, &updatedVersion);
958 ret = calendar_db_get_changes_by_version(_calendar_event._uri, calendarId, thisCalendar->getLastChangedVersion(), &list, &updatedVersion);
960 if( CALENDAR_ERROR_NONE!=ret ) {
961 ThrowMsg(PlatformException, "Can't get the updated item list: "<<ret);
964 ret = calendar_list_get_count(list, &count);
965 if( CALENDAR_ERROR_NONE!=ret ) {
966 ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
968 LoggerD("Item count: "<<count);
971 calendar_list_first(list);
973 calendar_record_h currentRecord = NULL;
976 currentRecord = NULL;
977 ret = calendar_list_get_current_record_p(list, ¤tRecord);
978 if ( CALENDAR_ERROR_NONE != ret ) {
979 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
982 ret = calendar_record_get_int(currentRecord, _calendar_updated_info.id ,&id);
983 if ( CALENDAR_ERROR_NONE != ret ) {
984 ThrowMsg(PlatformException, "Can't get updated info id: "<<ret);
987 ret = calendar_record_get_int(currentRecord, _calendar_updated_info.modified_status ,&type);
988 if ( CALENDAR_ERROR_NONE != ret ) {
989 ThrowMsg(PlatformException, "Can't get updated info modified status: "<<ret);
992 LoggerD("id "<<id<<", type "<<type);
993 if ( CALENDAR_EVENT_MODIFIED_STATUS_INSERTED==type ) {
994 eventPtr->setStatus(OnEventsChanged::ON_ADD);
995 } else if ( CALENDAR_EVENT_MODIFIED_STATUS_UPDATED==type ) {
996 eventPtr->setStatus(OnEventsChanged::ON_UPDATE);
997 } else if ( CALENDAR_EVENT_MODIFIED_STATUS_DELETED==type ) {
998 eventPtr->setStatus(OnEventsChanged::ON_DELETE);
1000 LoggerW("Wrong change type.");
1001 calendar_list_next(list);
1005 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisCalendar->getType()));
1007 eventWrapper->loadEvent(id);
1008 } Catch (NotFoundException){
1009 LoggerD("Handling deleted event with index: "<<id);
1011 eventPtr->addEvent(eventWrapper->getAbstractEvent());
1013 calendar_list_next(list);
1016 ret = calendar_db_get_current_version(&updatedVersion);
1017 if( CALENDAR_ERROR_NONE!=ret ) {
1018 ThrowMsg(PlatformException, "Can't get new version: "<<ret);
1021 thisCalendar->setLastChangedVersion(updatedVersion);
1022 LoggerD("Last change fetch version: "<<thisCalendar->getLastChangedVersion());
1024 eventPtr->setResult(true);
1025 eventPtr->setCalendarType(thisCalendar->getType());
1027 if( eventPtr->getEventList()->size() > 0 ) {
1028 thisCalendar->m_changeEmitters.emit(eventPtr);
1030 LoggerD("No actual changes. Skip signal emission.");
1035 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1039 calendar_list_destroy(list, true);
1043 void Calendar::OnRequestReceived(const IEventWatchChangesPtr &event)
1047 // Subscribe the watch to the platform just once.
1049 if( m_changeEmitters.size()==0 )
1051 const char *dataType;
1052 if(getType() == CalendarEvent::TASK_TYPE) {
1053 dataType = _calendar_todo._uri;
1055 dataType = _calendar_event._uri;
1058 ret = calendar_db_add_changed_cb(dataType, eventChangedCb, this);
1059 if( CALENDAR_ERROR_NONE!=ret ) {
1060 ThrowMsg(PlatformException, "Can't add db changed cb: "<<ret);
1062 // Save the last change fetch version to start watching.
1064 ret = calendar_db_get_current_version(&version);
1065 if( CALENDAR_ERROR_NONE!=ret ) {
1066 ThrowMsg(PlatformException, "Can't get version: "<<ret);
1068 setLastChangedVersion(version);
1069 LoggerD("Last change fetch version: "<<getLastChangedVersion());
1074 m_changeEmitters.attach(event->getEmitter());
1075 event->setWatchId(event->getEmitter()->getId());
1076 event->setResult(true);
1080 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1081 event->setResult(false);
1082 event->setExceptionCode(ExceptionCodes::UnknownException);
1086 void Calendar::OnRequestReceived(const IEventClearWatchPtr &event)
1090 if( m_changeEmitters.detach(event->getWatchId()) ) {
1091 if( m_changeEmitters.size()==0 ) {
1092 const char *dataType;
1093 if(getType() == CalendarEvent::TASK_TYPE) {
1094 dataType = _calendar_todo._uri;
1096 dataType = _calendar_event._uri;
1099 if( CALENDAR_ERROR_NONE!=calendar_db_remove_changed_cb(dataType, eventChangedCb, this) ) {
1100 ThrowMsg(PlatformException, "Can't remove change cb.");
1102 LoggerD("Platform watch cleared successfully.");
1105 event->setResult(true);
1107 LoggerD("Wrong watch Id.");
1108 event->setResult(false);
1113 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1114 event->setResult(false);
1115 event->setExceptionCode(ExceptionCodes::UnknownException);
1119 void Calendar::OnRequestReceived(const IEventExpandEventRecurrencePtr &event)
1121 const CalendarEventPtr calEvent = event->getEvent();
1122 const long long int startDate = event->getStartDate();
1123 const long long int endDate = event->getEndDate();
1124 bool isAllDay = calEvent->getIsAllDay();
1126 calendar_query_h query = NULL;
1127 calendar_filter_h filter = NULL;
1128 calendar_list_h list = NULL;
1131 if ( 0 >= calEvent->getRecurrenceRule()->getFrequency()) {
1132 ThrowMsg(InvalidArgumentException, "This is not a recurring event.");
1135 calendar_record_h currentRecord = NULL;
1136 int ret, currentRecordIndex, count=0;
1138 calendar_time_s st, et;
1139 if( true==isAllDay ) {
1140 st.type = CALENDAR_TIME_LOCALTIME;
1141 st.time.date = CalendarUtility::LLIToCalTime(calEvent->getTimeZone().c_str(), startDate).time.date;
1143 et.type = CALENDAR_TIME_LOCALTIME;
1144 et.time.date = CalendarUtility::LLIToCalTime(calEvent->getTimeZone().c_str(), endDate).time.date;
1146 st.type = CALENDAR_TIME_UTIME;
1147 st.time.utime = startDate;
1149 et.type = CALENDAR_TIME_UTIME;
1150 et.time.utime = endDate;
1153 if( true==isAllDay ) {
1154 ret = calendar_query_create(_calendar_instance_allday_calendar_book._uri, &query);
1156 ret = calendar_query_create(_calendar_instance_normal_calendar_book._uri, &query);
1158 if( CALENDAR_ERROR_NONE!=ret ) {
1159 ThrowMsg(PlatformException, "Creating a query failed: "<<ret);
1162 if( true==isAllDay ) {
1163 ret = calendar_filter_create(_calendar_instance_allday_calendar_book._uri, &filter);
1165 ret = calendar_filter_create(_calendar_instance_normal_calendar_book._uri, &filter);
1167 if( CALENDAR_ERROR_NONE!=ret ) {
1168 ThrowMsg(PlatformException, "Creating a filter failed: "<<ret);
1171 if( true==isAllDay ) {
1172 ret = calendar_filter_add_caltime(filter, _calendar_instance_allday_calendar_book.start_time, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL, st);
1174 ret = calendar_filter_add_caltime(filter, _calendar_instance_normal_calendar_book.start_time, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL, st);
1176 if( CALENDAR_ERROR_NONE!=ret ) {
1177 ThrowMsg(PlatformException, "Adding a caltime filter failed: "<<ret);
1180 ret = calendar_filter_add_operator(filter, CALENDAR_FILTER_OPERATOR_AND);
1181 if( CALENDAR_ERROR_NONE!=ret ) {
1182 ThrowMsg(PlatformException, "Adding a filter operator failed: "<<ret);
1185 if( true==isAllDay ) {
1186 ret = calendar_filter_add_caltime(filter, _calendar_instance_allday_calendar_book.end_time, CALENDAR_MATCH_LESS_THAN_OR_EQUAL, et);
1188 ret = calendar_filter_add_caltime(filter, _calendar_instance_normal_calendar_book.end_time, CALENDAR_MATCH_LESS_THAN_OR_EQUAL, et);
1190 if( CALENDAR_ERROR_NONE!=ret ) {
1191 ThrowMsg(PlatformException, "Adding a caltime filter failed: "<<ret);
1194 ret = calendar_query_set_filter(query, filter);
1195 if( CALENDAR_ERROR_NONE!=ret ) {
1196 ThrowMsg(PlatformException, "Setting a filter: "<<ret);
1199 ret = calendar_db_get_records_with_query(query, 0, 0, &list);
1200 if( CALENDAR_ERROR_NONE!=ret ) {
1201 ThrowMsg(PlatformException, "Getting event instances failed: "<<ret);
1204 ret = calendar_list_get_count(list, &count);
1205 if( CALENDAR_ERROR_NONE!=ret ) {
1206 ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
1208 LoggerD("Item count: "<<count<<", isAllDay: "<<isAllDay);
1211 calendar_list_first(list);
1215 currentRecord = NULL;
1216 ret = calendar_list_get_current_record_p(list, ¤tRecord);
1217 if ( CALENDAR_ERROR_NONE != ret ) {
1218 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
1221 if( true==isAllDay ) {
1222 ret = calendar_record_get_int(currentRecord, _calendar_instance_allday_calendar_book.event_id, ¤tRecordIndex);
1224 ret = calendar_record_get_int(currentRecord, _calendar_instance_normal_calendar_book.event_id, ¤tRecordIndex);
1226 if ( CALENDAR_ERROR_NONE != ret ) {
1227 ThrowMsg(PlatformException, "Can't get current record id: "<<ret);
1230 if(currentRecordIndex==calEvent->getId()) {
1231 DPL::ScopedPtr<EventWrapper> recurringEventWrapper(new EventWrapper(getType()));
1232 recurringEventWrapper->loadEvent(calEvent->getId());
1234 // Set distintive attributes of each instance.
1235 if( true==isAllDay ) {
1236 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_allday_calendar_book.start_time, &st);
1238 recurringEventWrapper->getAbstractEvent()->setRecurrenceId(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), st));
1239 recurringEventWrapper->getAbstractEvent()->setStartTime(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), st));
1241 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_normal_calendar_book.start_time, &st);
1243 recurringEventWrapper->getAbstractEvent()->setRecurrenceId(st.time.utime);
1244 recurringEventWrapper->getAbstractEvent()->setStartTime(st.time.utime);
1246 if ( CALENDAR_ERROR_NONE != ret ) {
1247 ThrowMsg(PlatformException, "Can't get current record start time: "<<ret);
1250 if( true==isAllDay ) {
1251 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_allday_calendar_book.end_time, &et);
1253 recurringEventWrapper->getAbstractEvent()->setEndTime(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), et));
1255 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_normal_calendar_book.end_time, &et);
1257 recurringEventWrapper->getAbstractEvent()->setEndTime(et.time.utime);
1259 if ( CALENDAR_ERROR_NONE != ret ) {
1260 ThrowMsg(PlatformException, "Can't get current record end time: "<<ret);
1263 LoggerD("Found a valid event instance with rid: "<<recurringEventWrapper->getAbstractEvent()->getRecurrenceId());
1265 event->addExpandedEvent(recurringEventWrapper->getAbstractEvent());
1267 LoggerD("Skip unmatched instance with event_id: "<<currentRecordIndex<<" and parent id: "<<calEvent->getId());
1270 calendar_list_next(list);
1272 LoggerD("Length of expanded events from parent: "<<event->getExpandedEventList()->size());
1275 calendar_query_destroy(query);
1279 calendar_filter_destroy(filter);
1283 calendar_list_destroy(list, true);
1287 // Consider the detached events also.
1288 currentRecord = NULL;
1289 int parentId = event->getEvent()->getId();
1291 ret = calendar_query_create(_calendar_event._uri, &query);
1292 if( CALENDAR_ERROR_NONE!=ret ) {
1293 ThrowMsg(PlatformException, "Creating a query failed: "<<ret);
1296 ret = calendar_filter_create(_calendar_event._uri, &filter);
1297 if( CALENDAR_ERROR_NONE!=ret ) {
1298 ThrowMsg(PlatformException, "Creating a filter failed: "<<ret);
1301 ret = calendar_filter_add_int(filter, _calendar_event.original_event_id, CALENDAR_MATCH_EQUAL, parentId);
1302 if( CALENDAR_ERROR_NONE!=ret ) {
1303 ThrowMsg(PlatformException, "Adding an int filter failed: "<<ret);
1306 ret = calendar_query_set_filter(query, filter);
1307 if( CALENDAR_ERROR_NONE!=ret ) {
1308 ThrowMsg(PlatformException, "Setting a filter: "<<ret);
1311 ret = calendar_db_get_records_with_query(query, 0, 0, &list);
1312 if(CALENDAR_ERROR_NONE!=ret) {
1313 ThrowMsg(PlatformException, "Finding detached instances failed: "<<ret);
1316 ret = calendar_list_get_count(list, &count);
1317 if( CALENDAR_ERROR_NONE!=ret ) {
1318 ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
1320 LoggerD("Item count: "<<count);
1323 calendar_list_first(list);
1327 currentRecord = NULL;
1328 ret = calendar_list_get_current_record_p(list, ¤tRecord);
1329 if ( CALENDAR_ERROR_NONE != ret ) {
1330 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
1333 ret = calendar_record_get_int(currentRecord, _calendar_event.id, ¤tRecordIndex);
1334 if ( CALENDAR_ERROR_NONE != ret ) {
1335 ThrowMsg(PlatformException, "Can't get current record id: "<<ret);
1338 st = {CALENDAR_TIME_UTIME, {0}};
1339 ret = calendar_record_get_caltime(currentRecord, _calendar_event.start_time, &st);
1340 if ( CALENDAR_ERROR_NONE != ret ) {
1341 ThrowMsg(PlatformException, "Can't get current record start time: "<<ret);
1344 et = {CALENDAR_TIME_UTIME, {0}};
1345 ret = calendar_record_get_caltime(currentRecord, _calendar_event.end_time, &et);
1346 if ( CALENDAR_ERROR_NONE != ret ) {
1347 ThrowMsg(PlatformException, "Can't get current record end time: "<<ret);
1350 if (st.time.utime>=startDate && et.time.utime<=endDate) {
1351 LoggerD("Found a valid detached event: "<<st.time.utime);
1352 DPL::ScopedPtr<EventWrapper> detachedEventWrapper(new EventWrapper(getType()));
1353 detachedEventWrapper->loadEvent(currentRecordIndex);
1355 // Set the same parent uid to each instances
1356 detachedEventWrapper->getAbstractEvent()->setId(parentId);
1357 // Set distintive attributes of each instance.
1358 detachedEventWrapper->getAbstractEvent()->setRecurrenceId(st.time.utime);
1359 detachedEventWrapper->getAbstractEvent()->setStartTime(st.time.utime);
1360 detachedEventWrapper->getAbstractEvent()->setEndTime(et.time.utime);
1362 event->addExpandedEvent(detachedEventWrapper->getAbstractEvent());
1365 calendar_list_next(list);
1368 LoggerD("Length of total expanded events: "<<event->getExpandedEventList()->size());
1370 event->setResult(true);
1373 calendar_query_destroy(query);
1377 calendar_filter_destroy(filter);
1381 calendar_list_destroy(list, true);
1385 Catch (InvalidArgumentException)
1387 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1388 event->setResult(false);
1389 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
1393 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1394 event->setResult(false);
1395 event->setExceptionCode(ExceptionCodes::UnknownException);
1399 calendar_query_destroy(query);
1402 calendar_filter_destroy(filter);
1405 calendar_list_destroy(list, true);