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.
19 #include <calendar2.h>
20 #include <dpl/log/log.h>
21 #include <dpl/scoped_ptr.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"
32 #include <IFilterVisitor.h>
36 using namespace WrtDeviceApis::Commons;
49 void Calendar::OnRequestReceived(const IEventAddEventPtr &event)
53 if (!event->getEvent()) {
54 ThrowMsg(NullPointerException, "Item parameter is NULL.");
56 if (event->getEvent()->getIdIsSet()) {
57 LogWarning("Non-null item id.");
58 event->getEvent()->resetId();
61 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
64 LogDebug("Set the default calendar id for a unified calendar item.");
65 event->getEvent()->setCalendarId(DEFAULT_EVENT_CALENDAR_BOOK_ID);
67 std::stringstream ss(getId());
70 event->getEvent()->setCalendarId(calendarId);
73 eventWrapper->convertAbstractEventToPlatformEvent();
75 eventWrapper->saveEvent();
77 event->setResult(true);
81 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
82 event->setResult(false);
83 event->setExceptionCode(ExceptionCodes::UnknownException);
87 void Calendar::OnRequestReceived(const IEventAddEventsPtr &event)
89 calendar_list_h listForAdd = NULL;
93 if (event->getEvents()->empty()) {
94 ThrowMsg(NullPointerException, "Item array is empty.");
98 calendar_record_h record = NULL;
101 ret = calendar_list_create(&listForAdd);
102 if (CALENDAR_ERROR_NONE != ret) {
103 ThrowMsg(PlatformException, "Can't create a list: "<<ret);
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.");
112 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(theItem, getType()));
115 LogDebug("Set the default calendar id for a unified calendar item.");
116 theItem->setCalendarId(DEFAULT_EVENT_CALENDAR_BOOK_ID);
118 std::stringstream ss(getId());
121 theItem->setCalendarId(calendarId);
124 eventWrapper->convertAbstractEventToPlatformEvent();
126 // Clone the record because the platform event will be freed by destructor.
128 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
129 if(CALENDAR_ERROR_NONE!=ret) {
130 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
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);
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);
143 LogDebug("Add records requst done with count: "<<count);
146 for(int i=0; i<count; i++) {
147 event->getEvents()->at(i)->setId(ids[i]);
154 event->setResult(true);
158 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
159 event->setResult(false);
160 event->setExceptionCode(ExceptionCodes::UnknownException);
164 calendar_list_destroy(listForAdd, true);
168 void Calendar::OnRequestReceived(const IEventUpdateEventPtr &event)
170 calendar_query_h query = NULL;
171 calendar_filter_h filter = NULL;
175 if (!event->getEvent()) {
176 ThrowMsg(NullPointerException, "Item object is NULL.");
179 CalendarEventPtr theItem = event->getEvent();
180 if (!theItem->getIdIsSet()) {
181 ThrowMsg(InvalidArgumentException, "Item id is not set.");
186 const char *dataType;
187 if(getType() == CalendarEvent::TASK_TYPE) {
188 dataType = _calendar_todo._uri;
190 dataType = _calendar_event._uri;
193 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(theItem, getType()));
194 eventWrapper->convertAbstractEventToPlatformEvent(true);
196 if ( event->getUpdateAllInstances() || 0>=theItem->getRecurrenceRule()->getFrequency()) {
197 // Platform detects the detached events and uptates all instances.
198 eventWrapper->saveEvent();
200 LogDebug("Update the exdate for a recurring parent event and add a new child event.");
202 // First update the parent event.
203 EventRecurrenceRulePtr rrule = theItem->getRecurrenceRule();
204 (*rrule->getExceptions()).push_back(theItem->getRecurrenceId());
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) {
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);
219 LogDebug("Set the exdate for the parent event: "<<exdate);
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.");
228 eventWrapper->saveEvent();
230 // Now add the detached child event.
231 EventRecurrenceRulePtr emptyRRule( new EventRecurrenceRule() );
232 // Detached event should not have rrule set.
233 theItem->setRecurrenceRule(emptyRRule);
235 theItem->setParentId(theItem->getId());
237 // Convert the modified child event.
238 eventWrapper->convertAbstractEventToPlatformEvent();
240 // Reset id for record insertion.
242 eventWrapper->saveEvent();
244 theItem->setIsDetached(true);
247 event->setResult(true);
251 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
252 event->setResult(false);
253 event->setExceptionCode(ExceptionCodes::UnknownException);
257 calendar_query_destroy(query);
260 calendar_filter_destroy(filter);
264 void Calendar::OnRequestReceived(const IEventUpdateEventsPtr &event)
266 calendar_list_h listForUpdate = NULL;
267 calendar_list_h listForAdd = NULL;
268 calendar_query_h query = NULL;
269 calendar_filter_h filter = NULL;
273 if (event->getEvents()->empty()) {
274 ThrowMsg(NullPointerException, "Item array is empty.");
278 calendar_record_h record = NULL;
280 const char *dataType;
281 if(getType() == CalendarEvent::TASK_TYPE) {
282 dataType = _calendar_todo._uri;
284 dataType = _calendar_event._uri;
287 ret = calendar_list_create(&listForUpdate);
288 if (CALENDAR_ERROR_NONE != ret) {
289 ThrowMsg(PlatformException, "Can't create a list for update: "<<ret);
291 ret = calendar_list_create(&listForAdd);
292 if (CALENDAR_ERROR_NONE != ret) {
293 ThrowMsg(PlatformException, "Can't create a list for add: "<<ret);
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.");
302 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisEvent, getType()));
303 eventWrapper->convertAbstractEventToPlatformEvent(true);
305 if( true==thisEvent->getIsDetached() ) {
306 // Treat the detached event same as the parent event.
308 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
309 if(CALENDAR_ERROR_NONE!=ret) {
310 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
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);
317 LogDebug("Added the detached event to the update list: "<<thisEvent->getId());
319 } else if (event->getUpdateAllInstances() || 0>=thisEvent->getRecurrenceRule()->getFrequency()) {
320 // Platform detects the detached events and uptates all instances.
322 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
323 if(CALENDAR_ERROR_NONE!=ret) {
324 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
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);
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);
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);
342 LogDebug("Saved the rid for the child: "<<thisEvent->getRecurrenceId());
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);
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);
356 ret = calendar_record_clone(eventWrapperChild->getPlatformEvent(), &record);
357 if(CALENDAR_ERROR_NONE!=ret) {
358 ThrowMsg(PlatformException, "Clonning the child event failed: "<<ret);
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);
366 thisEvent->setIsDetached(true);
368 // Now update the parent event.
369 EventRecurrenceRulePtr rrule = thisEvent->getRecurrenceRule();
370 (*rrule->getExceptions()).push_back(thisEvent->getRecurrenceId());
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) {
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);
385 LogDebug("Set the exdate for the parent event: "<<exdate);
389 ret = calendar_record_clone(eventWrapper->getPlatformEvent(), &record);
390 if(CALENDAR_ERROR_NONE!=ret) {
391 ThrowMsg(PlatformException, "Clonning the child event failed: "<<ret);
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);
401 // Perform the platform operations.
403 ret = calendar_list_get_count(listForAdd, &count);
404 if(CALENDAR_ERROR_NONE!=ret){
405 ThrowMsg(PlatformException, "Getting list count failed: "<<ret);
407 LogDebug("Final list count for add: "<<count);
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);
414 LogDebug("Add records requst done for update batch operation.");
419 ret = calendar_list_get_count(listForUpdate, &count);
420 if(CALENDAR_ERROR_NONE!=ret){
421 ThrowMsg(PlatformException, "Getting list count failed: "<<ret);
423 LogDebug("Final list count for update: "<<count);
426 ret = calendar_db_update_records(listForUpdate);
427 if (CALENDAR_ERROR_NONE != ret) {
428 ThrowMsg(PlatformException, "Can't update the item list: "<<ret);
430 LogDebug("Update records requst done for update batch operation.");
434 event->setResult(true);
438 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
439 event->setResult(false);
440 event->setExceptionCode(ExceptionCodes::UnknownException);
444 calendar_list_destroy(listForAdd, true);
447 calendar_list_destroy(listForUpdate, true);
450 calendar_query_destroy(query);
453 calendar_filter_destroy(filter);
457 void Calendar::OnRequestReceived(const IEventDeleteEventPtr &event)
461 if (!event->getEventId()) {
462 ThrowMsg(NullPointerException, "Item id is not set.");
465 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
466 event->getEventId()->setCalendarType(getType());
467 std::istringstream stream(event->getEventId()->getUId());
470 eventWrapper->getAbstractEvent()->setId(id);
472 std::stringstream ss(event->getEventId()->getRecurrenceId());
476 LogDebug("id: " << id << ", rid: " << rid);
478 eventWrapper->loadEvent(id);
480 // recurrence id is reset while loading the platform event.
481 eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
483 eventWrapper->deleteEvent();
484 event->setResult(true);
486 Catch (NotFoundException)
488 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
489 event->setResult(false);
490 event->setExceptionCode(ExceptionCodes::NotFoundException);
494 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
495 event->setResult(false);
496 event->setExceptionCode(ExceptionCodes::UnknownException);
500 void Calendar::OnRequestReceived(const IEventGetPtr &event)
504 if (!event->getItemId()) {
505 ThrowMsg(NullPointerException, "Id parameter is NULL");
508 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
509 std::stringstream ss(event->getItemId()->getUId());
513 eventWrapper->loadEvent(id);
515 event->setItem(eventWrapper->getAbstractEvent());
516 event->setResult(true);
518 Catch (NotFoundException)
520 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
521 event->setResult(false);
522 event->setExceptionCode(ExceptionCodes::NotFoundException);
526 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
527 event->setResult(false);
528 event->setExceptionCode(ExceptionCodes::UnknownException);
532 void Calendar::OnRequestReceived(const IEventDeleteEventsPtr &event)
534 calendar_list_h listForUpdate = NULL;
535 calendar_query_h query = NULL;
536 calendar_filter_h filter = NULL;
540 if (event->getEventIds()->empty()) {
541 ThrowMsg(NullPointerException, "Item id array is empty.");
544 std::vector<int> listForDelete;
545 std::vector<int> listForDetached;
546 std::vector<int> listForDetachedParent;
550 calendar_record_h item, record;
551 const char *dataType = NULL;
553 ret = calendar_list_create(&listForUpdate);
554 if (CALENDAR_ERROR_NONE != ret) {
555 ThrowMsg(PlatformException, "Can't create a list for update: "<<ret);
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());
562 std::istringstream stream(event->getEventIds()->at(i)->getUId());
564 eventWrapper->getAbstractEvent()->setId(id);
566 eventWrapper->loadEvent(id);
567 item = eventWrapper->getPlatformEvent();
569 std::stringstream ss(event->getEventIds()->at(i)->getRecurrenceId());
571 eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
573 // If the recurrenceId is set, delete the instance of recurring event only.
574 LogDebug("id to delete: " << id << ", rid: " << rid << ", type: " << getType());
577 if(getType() == CalendarEvent::TASK_TYPE) {
578 dataType = _calendar_todo._uri;
580 dataType = _calendar_event._uri;
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. */
586 listForDelete.push_back(id);
587 } else if (true==eventWrapper->getAbstractEvent()->getIsDetached() ) {
588 listForDetached.push_back(id);
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);
595 listForDetachedParent.push_back(parentId);
596 LogDebug("Added the detached event id: "<<id<<", parent id: "<<parentId);
598 EventRecurrenceRulePtr rrule = eventWrapper->getAbstractEvent()->getRecurrenceRule();
599 (*rrule->getExceptions()).push_back(rid);
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) {
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);
614 LogDebug("Set the exdate: "<<exdate);
618 ret = calendar_record_clone(item, &record);
619 if(CALENDAR_ERROR_NONE!=ret) {
620 ThrowMsg(PlatformException, "Clonning failed: "<<ret);
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);
627 LogDebug("Calendar item instance added for update.");
631 // Perform the platform operations.
632 // Uptate operatoin should be done first not to update records after deletion.
634 ret = calendar_list_get_count(listForUpdate, &count);
635 if(CALENDAR_ERROR_NONE!=ret){
636 LogWarning("Getting list count for update failed: "<<ret);
638 LogDebug("Final list count for update: "<<count);
641 ret = calendar_db_update_records(listForUpdate);
642 if (CALENDAR_ERROR_NONE != ret) {
643 ThrowMsg(PlatformException, "Can't update the item list: "<<ret);
645 LogDebug("Update records requst done for update batch operation.");
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);
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));
659 LogDebug("The parent id is already included to the delete list: "<<listForDetachedParent.at(count));
662 count = listForDelete.size();
664 LogDebug("Final list count for deletion: "<<count);
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);
670 LogDebug("Delete records requst done for delete batch operation.");
674 event->setResult(true);
676 Catch (NotFoundException)
678 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
679 event->setResult(false);
680 event->setExceptionCode(ExceptionCodes::NotFoundException);
684 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
685 event->setResult(false);
686 event->setExceptionCode(ExceptionCodes::UnknownException);
690 calendar_query_destroy(query);
693 calendar_filter_destroy(filter);
696 calendar_list_destroy(listForUpdate, true);
700 void Calendar::OnRequestReceived(const IEventFindEventsPtr &event)
704 CalendarFilterPtr calendarFilter( new CalendarFilter() );
706 calendarFilter->setType(getType());
707 LogDebug("Default filter created with type "<<getType());
709 DeviceAPI::Tizen::IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<DeviceAPI::Tizen::IFilterVisitor>(calendarFilter);
712 std::stringstream ss(getId());
714 if (event->getGenericFilterIsSet()) {
715 DeviceAPI::Tizen::FilterPtr genericFilter = event->getGenericFilter();
717 DeviceAPI::Tizen::FilterValidatorPtr validator = CalendarFilterValidatorFactory::getCalendarFilterValidator();
718 bool success = genericFilter->validate(validator);
720 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
722 LogDebug("Filter validation has passed.");
725 genericFilter->travel(filterTraversal, 0);
728 LogDebug("Set all calendars flag for a unified calendar.");
729 calendarFilter->setCalendarId(CALENDAR_BOOK_FILTER_ALL, true);
731 LogDebug("Set additional calendar id: "<<calendarId);
732 calendarFilter->setCalendarId(calendarId, true);
736 LogDebug("Set all calendars flag for a unified calendar.");
737 calendarFilter->setCalendarId(CALENDAR_BOOK_FILTER_ALL, false);
739 LogDebug("Set calendar id: "<<calendarId);
740 calendarFilter->setCalendarId(calendarId, false);
744 if (event->getSortModesIsSet()) {
745 calendarFilter->setSortMode(event->getSortModes());
748 calendarFilter->executeQuery();
750 LogDebug("Return the query result after conversion.");
752 calendar_list_h resultList = calendarFilter->getResultRecordList();
754 int count = calendarFilter->getResultRecordCount();
755 calendar_record_h currentRecord = NULL;
757 calendar_list_first(resultList);
760 currentRecord = NULL;
761 ret = calendar_list_get_current_record_p(resultList, ¤tRecord);
762 if ( CALENDAR_ERROR_NONE != ret ) {
763 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
766 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(currentRecord, getType()));
767 event->addEvent(eventWrapper->convertPlatformEventToAbstractEvent());
769 calendar_list_next(resultList);
771 LogDebug("Length of found items: "<<event->getEvents()->size());
773 // Handle the recurring event range filter corner case.
774 int id = -1, parentCount = -1;
776 resultList = calendarFilter->getNormalInstanceResultRecordList();
777 count = calendarFilter->getNormalInstanceResultRecordCount();
778 LogDebug("Number of found normal instances: "<<count);
780 currentRecord = NULL;
781 calendar_list_first(resultList);
783 currentRecord = NULL;
784 ret = calendar_list_get_current_record_p(resultList, ¤tRecord);
785 if ( CALENDAR_ERROR_NONE != ret ) {
786 ThrowMsg(PlatformException, "Can't get a current record: "<<ret);
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);
795 // Skip if the parent event is already found.
796 parentCount = event->getEvents()->size();
798 while(parentCount--) {
799 if(id==event->getEvents()->at(parentCount)->getId()) {
800 LogDebug("Found the id: "<<id<<", thus skip this.");
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());
813 calendar_list_next(resultList);
815 LogDebug("Length of found items including normal instances: "<<event->getEvents()->size());
817 resultList = calendarFilter->getAlldayInstanceResultRecordList();
818 count = calendarFilter->getAlldayInstanceResultRecordCount();
819 LogDebug("Number of found allday instances: "<<count);
821 currentRecord = NULL;
822 calendar_list_first(resultList);
824 currentRecord = NULL;
825 ret = calendar_list_get_current_record_p(resultList, ¤tRecord);
826 if ( CALENDAR_ERROR_NONE != ret ) {
827 ThrowMsg(PlatformException, "Can't get a current record: "<<ret);
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);
836 // Skip if the parent event is already found.
837 parentCount = event->getEvents()->size();
839 while(parentCount--) {
840 if(id==event->getEvents()->at(parentCount)->getId()) {
841 LogDebug("Found the id: "<<id<<", thus skip this.");
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());
854 calendar_list_next(resultList);
856 LogDebug("Length of found items including allday instances: "<<event->getEvents()->size());
858 event->setResult(true);
860 Catch (InvalidArgumentException)
862 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
863 event->setResult(false);
864 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
866 Catch (NotFoundException)
868 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
869 event->setResult(false);
870 event->setExceptionCode(ExceptionCodes::NotFoundException);
874 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
875 event->setResult(false);
876 event->setExceptionCode(ExceptionCodes::UnknownException);
880 void Calendar::OnRequestReceived(const IEventCreateEventFromStringPtr &event)
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);
890 Catch(PlatformException)
892 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
893 LogDebug("eventString: " + event->getEventString());
894 event->setResult(false);
895 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
899 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
900 LogDebug("eventString: " + event->getEventString());
901 event->setResult(false);
902 event->setExceptionCode(ExceptionCodes::UnknownException);
906 void Calendar::OnRequestReceived(const IEventExportEventToStringPtr &event)
910 if (!event->getEvent()) {
911 ThrowMsg(NullPointerException, "event parameter is NULL");
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);
922 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
923 event->setResult(false);
924 event->setExceptionCode(ExceptionCodes::UnknownException);
928 static void eventChangedCb(const char *view_uri, void *user_data)
930 LogDebug("Items change cb with view_uri: "<<view_uri);
932 OnEventsChangedPtr eventPtr(new OnEventsChanged());
933 calendar_list_h list = NULL;
937 if (user_data == NULL) {
938 LogDebug("user_data is NULL.");
942 Calendar *thisCalendar = (Calendar*) user_data;
944 int ret, id, type, updatedVersion, calendarId, count = 0;
947 if(thisCalendar->getIsUnified()) {
948 LogDebug("Set the all calendar id for a unified calendar.");
949 calendarId = CALENDAR_BOOK_FILTER_ALL;
951 std::stringstream ss(thisCalendar->getId());
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);
959 ret = calendar_db_get_changes_by_version(_calendar_event._uri, calendarId, thisCalendar->getLastChangedVersion(), &list, &updatedVersion);
961 if( CALENDAR_ERROR_NONE!=ret ) {
962 ThrowMsg(PlatformException, "Can't get the updated item list: "<<ret);
965 ret = calendar_list_get_count(list, &count);
966 if( CALENDAR_ERROR_NONE!=ret ) {
967 ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
969 LogDebug("Item count: "<<count);
972 calendar_list_first(list);
974 calendar_record_h currentRecord = NULL;
977 currentRecord = NULL;
978 ret = calendar_list_get_current_record_p(list, ¤tRecord);
979 if ( CALENDAR_ERROR_NONE != ret ) {
980 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
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);
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);
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);
1001 LogWarning("Wrong change type.");
1002 calendar_list_next(list);
1006 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisCalendar->getType()));
1008 eventWrapper->loadEvent(id);
1009 } Catch (NotFoundException){
1010 LogDebug("Handling deleted event with index: "<<id);
1012 eventPtr->addEvent(eventWrapper->getAbstractEvent());
1014 calendar_list_next(list);
1017 ret = calendar_db_get_current_version(&updatedVersion);
1018 if( CALENDAR_ERROR_NONE!=ret ) {
1019 ThrowMsg(PlatformException, "Can't get new version: "<<ret);
1022 thisCalendar->setLastChangedVersion(updatedVersion);
1023 LogDebug("Last change fetch version: "<<thisCalendar->getLastChangedVersion());
1025 eventPtr->setResult(true);
1026 eventPtr->setCalendarType(thisCalendar->getType());
1028 if( eventPtr->getEventList()->size() > 0 ) {
1029 thisCalendar->m_changeEmitters.emit(eventPtr);
1031 LogDebug("No actual changes. Skip signal emission.");
1036 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1040 calendar_list_destroy(list, true);
1044 void Calendar::OnRequestReceived(const IEventWatchChangesPtr &event)
1048 // Subscribe the watch to the platform just once.
1050 if( m_changeEmitters.size()==0 )
1052 const char *dataType;
1053 if(getType() == CalendarEvent::TASK_TYPE) {
1054 dataType = _calendar_todo._uri;
1056 dataType = _calendar_event._uri;
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);
1063 // Save the last change fetch version to start watching.
1065 ret = calendar_db_get_current_version(&version);
1066 if( CALENDAR_ERROR_NONE!=ret ) {
1067 ThrowMsg(PlatformException, "Can't get version: "<<ret);
1069 setLastChangedVersion(version);
1070 LogDebug("Last change fetch version: "<<getLastChangedVersion());
1075 m_changeEmitters.attach(event->getEmitter());
1076 event->setWatchId(event->getEmitter()->getId());
1077 event->setResult(true);
1081 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1082 event->setResult(false);
1083 event->setExceptionCode(ExceptionCodes::UnknownException);
1087 void Calendar::OnRequestReceived(const IEventClearWatchPtr &event)
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;
1097 dataType = _calendar_event._uri;
1100 if( CALENDAR_ERROR_NONE!=calendar_db_remove_changed_cb(dataType, eventChangedCb, this) ) {
1101 ThrowMsg(PlatformException, "Can't remove change cb.");
1103 LogDebug("Platform watch cleared successfully.");
1106 event->setResult(true);
1108 LogDebug("Wrong watch Id.");
1109 event->setResult(false);
1114 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1115 event->setResult(false);
1116 event->setExceptionCode(ExceptionCodes::UnknownException);
1120 void Calendar::OnRequestReceived(const IEventExpandEventRecurrencePtr &event)
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();
1127 calendar_query_h query = NULL;
1128 calendar_filter_h filter = NULL;
1129 calendar_list_h list = NULL;
1132 if ( 0 >= calEvent->getRecurrenceRule()->getFrequency()) {
1133 ThrowMsg(InvalidArgumentException, "This is not a recurring event.");
1136 calendar_record_h currentRecord = NULL;
1137 int ret, currentRecordIndex, count=0;
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;
1144 et.type = CALENDAR_TIME_LOCALTIME;
1145 et.time.date = CalendarUtility::LLIToCalTime(calEvent->getTimeZone().c_str(), endDate).time.date;
1147 st.type = CALENDAR_TIME_UTIME;
1148 st.time.utime = startDate;
1150 et.type = CALENDAR_TIME_UTIME;
1151 et.time.utime = endDate;
1154 if( true==isAllDay ) {
1155 ret = calendar_query_create(_calendar_instance_allday_calendar_book._uri, &query);
1157 ret = calendar_query_create(_calendar_instance_normal_calendar_book._uri, &query);
1159 if( CALENDAR_ERROR_NONE!=ret ) {
1160 ThrowMsg(PlatformException, "Creating a query failed: "<<ret);
1163 if( true==isAllDay ) {
1164 ret = calendar_filter_create(_calendar_instance_allday_calendar_book._uri, &filter);
1166 ret = calendar_filter_create(_calendar_instance_normal_calendar_book._uri, &filter);
1168 if( CALENDAR_ERROR_NONE!=ret ) {
1169 ThrowMsg(PlatformException, "Creating a filter failed: "<<ret);
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);
1175 ret = calendar_filter_add_caltime(filter, _calendar_instance_normal_calendar_book.start_time, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL, st);
1177 if( CALENDAR_ERROR_NONE!=ret ) {
1178 ThrowMsg(PlatformException, "Adding a caltime filter failed: "<<ret);
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);
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);
1189 ret = calendar_filter_add_caltime(filter, _calendar_instance_normal_calendar_book.end_time, CALENDAR_MATCH_LESS_THAN_OR_EQUAL, et);
1191 if( CALENDAR_ERROR_NONE!=ret ) {
1192 ThrowMsg(PlatformException, "Adding a caltime filter failed: "<<ret);
1195 ret = calendar_query_set_filter(query, filter);
1196 if( CALENDAR_ERROR_NONE!=ret ) {
1197 ThrowMsg(PlatformException, "Setting a filter: "<<ret);
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);
1205 ret = calendar_list_get_count(list, &count);
1206 if( CALENDAR_ERROR_NONE!=ret ) {
1207 ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
1209 LogDebug("Item count: "<<count<<", isAllDay: "<<isAllDay);
1212 calendar_list_first(list);
1216 currentRecord = NULL;
1217 ret = calendar_list_get_current_record_p(list, ¤tRecord);
1218 if ( CALENDAR_ERROR_NONE != ret ) {
1219 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
1222 if( true==isAllDay ) {
1223 ret = calendar_record_get_int(currentRecord, _calendar_instance_allday_calendar_book.event_id, ¤tRecordIndex);
1225 ret = calendar_record_get_int(currentRecord, _calendar_instance_normal_calendar_book.event_id, ¤tRecordIndex);
1227 if ( CALENDAR_ERROR_NONE != ret ) {
1228 ThrowMsg(PlatformException, "Can't get current record id: "<<ret);
1231 if(currentRecordIndex==calEvent->getId()) {
1232 DPL::ScopedPtr<EventWrapper> recurringEventWrapper(new EventWrapper(getType()));
1233 recurringEventWrapper->loadEvent(calEvent->getId());
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);
1239 recurringEventWrapper->getAbstractEvent()->setRecurrenceId(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), st));
1240 recurringEventWrapper->getAbstractEvent()->setStartTime(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), st));
1242 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_normal_calendar_book.start_time, &st);
1244 recurringEventWrapper->getAbstractEvent()->setRecurrenceId(st.time.utime);
1245 recurringEventWrapper->getAbstractEvent()->setStartTime(st.time.utime);
1247 if ( CALENDAR_ERROR_NONE != ret ) {
1248 ThrowMsg(PlatformException, "Can't get current record start time: "<<ret);
1251 if( true==isAllDay ) {
1252 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_allday_calendar_book.end_time, &et);
1254 recurringEventWrapper->getAbstractEvent()->setEndTime(CalendarUtility::calTimeToLLI(calEvent->getTimeZone().c_str(), et));
1256 ret = calendar_record_get_caltime(currentRecord, _calendar_instance_normal_calendar_book.end_time, &et);
1258 recurringEventWrapper->getAbstractEvent()->setEndTime(et.time.utime);
1260 if ( CALENDAR_ERROR_NONE != ret ) {
1261 ThrowMsg(PlatformException, "Can't get current record end time: "<<ret);
1264 LogDebug("Found a valid event instance with rid: "<<recurringEventWrapper->getAbstractEvent()->getRecurrenceId());
1266 event->addExpandedEvent(recurringEventWrapper->getAbstractEvent());
1269 calendar_list_next(list);
1271 LogDebug("Length of expanded events from parent: "<<event->getExpandedEventList()->size());
1274 calendar_query_destroy(query);
1278 calendar_filter_destroy(filter);
1282 calendar_list_destroy(list, true);
1286 // Consider the detached events also.
1287 currentRecord = NULL;
1288 int parentId = event->getEvent()->getId();
1290 ret = calendar_query_create(_calendar_event._uri, &query);
1291 if( CALENDAR_ERROR_NONE!=ret ) {
1292 ThrowMsg(PlatformException, "Creating a query failed: "<<ret);
1295 ret = calendar_filter_create(_calendar_event._uri, &filter);
1296 if( CALENDAR_ERROR_NONE!=ret ) {
1297 ThrowMsg(PlatformException, "Creating a filter failed: "<<ret);
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);
1305 ret = calendar_query_set_filter(query, filter);
1306 if( CALENDAR_ERROR_NONE!=ret ) {
1307 ThrowMsg(PlatformException, "Setting a filter: "<<ret);
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);
1315 ret = calendar_list_get_count(list, &count);
1316 if( CALENDAR_ERROR_NONE!=ret ) {
1317 ThrowMsg(PlatformException, "Can't get the item count: "<<ret);
1319 LogDebug("Item count: "<<count);
1322 calendar_list_first(list);
1326 currentRecord = NULL;
1327 ret = calendar_list_get_current_record_p(list, ¤tRecord);
1328 if ( CALENDAR_ERROR_NONE != ret ) {
1329 ThrowMsg(PlatformException, "Can't get current record: "<<ret);
1332 ret = calendar_record_get_int(currentRecord, _calendar_event.id, ¤tRecordIndex);
1333 if ( CALENDAR_ERROR_NONE != ret ) {
1334 ThrowMsg(PlatformException, "Can't get current record id: "<<ret);
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);
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);
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);
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);
1361 event->addExpandedEvent(detachedEventWrapper->getAbstractEvent());
1364 calendar_list_next(list);
1367 LogDebug("Length of total expanded events: "<<event->getExpandedEventList()->size());
1369 event->setResult(true);
1372 calendar_query_destroy(query);
1376 calendar_filter_destroy(filter);
1380 calendar_list_destroy(list, true);
1384 Catch (InvalidArgumentException)
1386 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1387 event->setResult(false);
1388 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
1392 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
1393 event->setResult(false);
1394 event->setExceptionCode(ExceptionCodes::UnknownException);
1398 calendar_query_destroy(query);
1401 calendar_filter_destroy(filter);
1404 calendar_list_destroy(list, true);