2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <calendar-svc-provider.h>
19 #include <dpl/log/log.h>
20 #include <dpl/scoped_ptr.h>
22 #include "CalendarManager.h"
23 #include "CalendarQuery.h"
24 #include "CalendarFilter.h"
25 #include "CalendarFilterValidator.h"
26 #include "API/Calendar/OnAddEventsChanged.h"
27 #include "API/Calendar/OnUpdateEventsChanged.h"
28 #include "API/Calendar/OnDeleteEventsChanged.h"
29 #include "API/Calendar/OnEventsChanged.h"
30 #include "API/Calendar/IEventWatchChanges.h"
31 #include "API/Calendar/IEventClearWatch.h"
32 #include "API/Calendar/EventId.h"
33 #include <API/Filter/IFilter.h>
34 #include <API/Filter/IFilterVisitor.h>
37 using namespace TizenApis::Api::Calendar;
38 using namespace WrtDeviceApis::Commons;
54 void Calendar::OnRequestReceived(const IEventAddEventPtr &event)
59 if (!event->getEvent()) {
60 ThrowMsg(NullPointerException, "event parameter is NULL");
62 if (event->getEvent()->getIdIsSet()) {
63 LogWarning("adding event that is already added");
64 event->getEvent()->resetId();
66 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
67 event->getEvent()->setCalendarType(getType());
68 eventWrapper->convertAbstractEventToPlatformEvent();
69 if (event->checkCancelled()) {
70 event->setCancelAllowed(true);
71 event->setResult(true);
75 // Set the account and calendar id before saving the item.
76 eventWrapper->setCalendarId(getId());
77 eventWrapper->setCalendarAccountId(getAccountId());
78 eventWrapper->saveEvent();
79 event->setResult(true);
81 catch (const Exception &ex)
83 LogError("Error during adding event" << ex.DumpToString());
84 event->setResult(false);
85 event->setExceptionCode(ExceptionCodes::UnknownException);
87 event->setCancelAllowed(false);
90 void Calendar::OnRequestReceived(const IEventAddEventsPtr &events)
95 if (events->getEvents()->empty()) {
96 ThrowMsg(NullPointerException, "event vector parameter is empty");
99 // Save the vector of events iteratively
100 bool failedAdding = false;
101 for(unsigned int i=0; i<events->getEvents()->size(); i++)
103 if (events->getEvents()->at(i)->getIdIsSet()) {
104 LogWarning("adding event that is already added: index " << i);
105 events->getEvents()->at(i)->resetId();
107 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(events->getEvents()->at(i), getType()));
108 events->getEvents()->at(i)->setCalendarType(getType());
109 eventWrapper->convertAbstractEventToPlatformEvent();
110 if (events->checkCancelled()) {
111 events->setCancelAllowed(true);
112 events->setResult(true);
117 // Set the account and calendar id before saving the item.
118 eventWrapper->setCalendarId(getId());
119 eventWrapper->setCalendarAccountId(getAccountId());
120 eventWrapper->saveEvent();
121 } catch (const Exception &saveException) {
122 LogInfo("Error during saving an event " << saveException.DumpToString());
125 //getAddEmitter()->emit(eventPtr);
128 if( false==failedAdding ) {
129 events->setResult(true);
131 events->setResult(false);
134 catch (const Exception &ex)
136 LogError("Error during adding events" << ex.DumpToString());
137 events->setResult(false);
138 events->setExceptionCode(ExceptionCodes::UnknownException);
140 events->setCancelAllowed(false);
143 void Calendar::OnRequestReceived(const IEventUpdateEventPtr &event)
148 if (!event->getEvent()) {
149 ThrowMsg(NullPointerException, "event parameter is NULL");
151 if (!event->getEvent()->getIdIsSet()) {
153 InvalidArgumentException,
154 "Cannot update non-existing event. Event needs adding or ID is wrong");
156 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
157 event->getEvent()->setCalendarType(getType());
158 eventWrapper->convertAbstractEventToPlatformEvent();
159 if (event->checkCancelled()) {
160 event->setCancelAllowed(true);
161 event->setResult(true);
165 if ( event->getUpdateAllInstances() || NULL==event->getEvent()->getRecurrenceRule())
167 // Set the account and calendar id before saving the item.
168 eventWrapper->setCalendarId(getId());
169 eventWrapper->setCalendarAccountId(getAccountId());
170 eventWrapper->saveEvent();
174 LogDebug("Update the exception record");
175 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(event->getEvent(), getType()));
176 eventWrapperChild->convertAbstractEventToPlatformEvent();
178 if ( CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
179 CAL_VALUE_INT_ORIGINAL_EVENT_ID, event->getEvent()->getId()) ) {
180 ThrowMsg(PlatformException, "cannot save exception event");
182 if (CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
183 CAL_VALUE_INT_REPEAT_TERM,0) ) {
184 ThrowMsg(PlatformException, "cannot save exception event");
186 int childId = calendar_svc_insert(eventWrapperChild->getPlatformEvent());
188 ThrowMsg(PlatformException, "cannot save exception event");
192 cal_value *value = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE);
193 if (CAL_SUCCESS!=calendar_svc_value_set_time(value, CAL_VALUE_GMT_EXCEPTION_DATE_TIME, CAL_TZ_FLAG_GMT, event->getEvent()->getStartTime()) ) {
194 ThrowMsg(PlatformException, "cannot save the exception parent event");
196 if (CAL_SUCCESS!=calendar_svc_value_set_int(value, CAL_VALUE_INT_EXCEPTION_DATE_ID, childId)) {
197 ThrowMsg(PlatformException, "cannot save the exception parent event");
199 eventWrapper->loadEvent(event->getEvent()->getId());
200 calendar_svc_struct_get_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, &list);
201 list = g_list_append(list, value);
202 if (CAL_SUCCESS!=calendar_svc_struct_store_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, list)) {
203 ThrowMsg(PlatformException, "cannot save the exception parent event");
205 calendar_svc_update(eventWrapper->getPlatformEvent());
207 event->getEvent()->setIsDetached(true);
210 event->setResult(true);
212 catch (const Exception &ex)
214 LogError("Error during updating event " << ex.DumpToString());
215 event->setResult(false);
216 event->setExceptionCode(ExceptionCodes::UnknownException);
218 event->setCancelAllowed(false);
221 void Calendar::OnRequestReceived(const IEventUpdateEventsPtr &events)
226 if (events->getEvents()->empty()) {
227 ThrowMsg(NullPointerException, "event vector parameter is empty");
230 // Update the vector of events iteratively
231 bool failedUpdating = false;
232 for(unsigned int i=0; i<events->getEvents()->size(); i++)
234 CalendarEventPtr thisEvent = events->getEvents()->at(i);
235 if (!thisEvent->getIdIsSet()) {
236 ThrowMsg(InvalidArgumentException,
237 "Cannot update non-existing event. Event needs adding or ID is wrong");
239 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisEvent, getType()));
240 events->getEvents()->at(i)->setCalendarType(getType());
241 eventWrapper->convertAbstractEventToPlatformEvent();
242 if (events->checkCancelled()) {
243 events->setCancelAllowed(true);
244 events->setResult(true);
249 if (events->getUpdateAllInstances() || NULL==thisEvent->getRecurrenceRule())
251 // Set the account and calendar id before saving the item.
252 eventWrapper->setCalendarId(getId());
253 eventWrapper->setCalendarAccountId(getAccountId());
254 eventWrapper->saveEvent();
258 LogDebug("Update the exception record");
259 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(thisEvent, getType()));
260 eventWrapperChild->convertAbstractEventToPlatformEvent();
262 if ( CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
263 CAL_VALUE_INT_ORIGINAL_EVENT_ID, thisEvent->getId()) ) {
264 ThrowMsg(PlatformException, "cannot save exception event");
266 if (CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
267 CAL_VALUE_INT_REPEAT_TERM,0) ) {
268 ThrowMsg(PlatformException, "cannot save exception event");
270 int childId = calendar_svc_insert(eventWrapperChild->getPlatformEvent());
272 ThrowMsg(PlatformException, "cannot save exception event");
276 cal_value *value = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE);
277 if (CAL_SUCCESS!=calendar_svc_value_set_time(value, CAL_VALUE_GMT_EXCEPTION_DATE_TIME, CAL_TZ_FLAG_GMT, thisEvent->getStartTime()) ) {
278 ThrowMsg(PlatformException, "cannot save the exception parent event");
280 if (CAL_SUCCESS!=calendar_svc_value_set_int(value, CAL_VALUE_INT_EXCEPTION_DATE_ID, childId)) {
281 ThrowMsg(PlatformException, "cannot save the exception parent event");
283 calendar_svc_struct_get_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, &list);
284 list = g_list_append(list, value);
285 if (CAL_SUCCESS!=calendar_svc_struct_store_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, list)) {
286 ThrowMsg(PlatformException, "cannot save the exception parent event");
288 calendar_svc_update(eventWrapper->getPlatformEvent());
290 thisEvent->setIsDetached(true);
292 } catch (const Exception &updateException) {
293 LogInfo("Error during updating an event " << updateException.DumpToString());
294 failedUpdating = true;
296 //getUpdateEmitter()->emit(eventPtr);
299 if( false==failedUpdating ) {
300 events->setResult(true);
302 events->setResult(false);
305 catch (const Exception &ex)
307 LogError("Error during updating events " << ex.DumpToString());
308 events->setResult(false);
309 events->setExceptionCode(ExceptionCodes::UnknownException);
311 events->setCancelAllowed(false);
314 void Calendar::OnRequestReceived(const IEventDeleteEventPtr &event)
319 if (!event->getEventId()) {
320 ThrowMsg(NullPointerException, "event Id parameter is NULL");
323 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
324 event->getEventId()->setCalendarType(getType());
325 std::istringstream stream(event->getEventId()->getUId());
328 //eventWrapper->getAbstractEvent()->setId(id);
329 eventWrapper->loadEvent(id);
330 LogDebug("event->getEventId()->getRecurrenceId() : " << event->getEventId()->getRecurrenceId());
331 eventWrapper->getAbstractEvent()->setRecurrenceId(event->getEventId()->getRecurrenceId());
333 if (event->checkCancelled()) {
334 event->setCancelAllowed(true);
335 event->setResult(true);
339 eventWrapper->deleteEvent();
340 event->setResult(true);
342 catch (const NotFoundException &ex)
344 LogError("event doesn't exist");
345 event->setResult(false);
346 event->setExceptionCode(ExceptionCodes::NotFoundException);
348 catch (const Exception &ex)
350 LogError("Error during deleting event " << ex.DumpToString());
351 event->setResult(false);
352 event->setExceptionCode(ExceptionCodes::UnknownException);
354 event->setCancelAllowed(false);
357 void Calendar::OnRequestReceived(const IEventGetPtr &event)
362 if (!event->getItemId()) {
363 ThrowMsg(NullPointerException, "Id parameter is NULL");
366 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
367 event->getItemId()->setCalendarType(getType());
368 std::stringstream ss(event->getItemId()->getUId());
371 eventWrapper->loadEvent(id);
373 event->setItem(eventWrapper->convertPlatformEventToAbstractEvent());
374 event->getItem()->setCalendarType(getType());
375 event->setResult(true);
377 catch (const NotFoundException &ex)
379 LogError("Item doesn't exist");
380 event->setResult(false);
381 event->setExceptionCode(ExceptionCodes::NotFoundException);
383 catch (const Exception &ex)
385 LogError("Error during getting an item " << ex.DumpToString());
386 event->setResult(false);
387 event->setExceptionCode(ExceptionCodes::UnknownException);
389 event->setCancelAllowed(false);
392 void Calendar::OnRequestReceived(const IEventDeleteEventsPtr &events)
397 if (events->getEventIds()->empty()) {
398 ThrowMsg(NullPointerException, "event vector parameter is empty");
401 // Delete the vector of events iteratively considering the recurrenceId
402 bool failedDeleting = false;
403 for(unsigned int i=0; i<events->getEventIds()->size(); i++)
405 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
406 events->getEventIds()->at(i)->setCalendarType(getType());
407 std::istringstream stream(events->getEventIds()->at(i)->getUId());
410 eventWrapper->getAbstractEvent()->setId(id);
411 eventWrapper->getAbstractEvent()->setRecurrenceId(events->getEventIds()->at(i)->getRecurrenceId());
412 eventWrapper->convertAbstractEventToPlatformEvent();
413 if (events->checkCancelled()) {
414 events->setCancelAllowed(true);
415 events->setResult(true);
420 eventWrapper->deleteEvent();
421 } catch (const NotFoundException &ex) {
422 LogInfo("Event not found during deleting an event.");
423 events->setExceptionCode(ExceptionCodes::NotFoundException);
424 failedDeleting = true;
425 } catch (const Exception &ex) {
426 LogInfo("Exception occurred during deleting an event.");
427 events->setExceptionCode(ExceptionCodes::PlatformException);
428 failedDeleting = true;
432 if( false==failedDeleting ) {
433 events->setResult(true);
436 events->setResult(false);
439 catch (const NotFoundException &ex)
441 LogError("event doesn't exist");
442 events->setResult(false);
443 events->setExceptionCode(ExceptionCodes::NotFoundException);
445 catch (const Exception &ex)
447 LogError("Error during deleting event " << ex.DumpToString());
448 events->setResult(false);
449 events->setExceptionCode(ExceptionCodes::UnknownException);
451 events->setCancelAllowed(false);
454 void Calendar::OnRequestReceived(const IEventFindEventsPtr &event)
457 bool useGenericFilter = true;
458 event->setResult(true);
460 // Tizen Generic filter
461 if ( useGenericFilter )
467 CalendarFilterPtr calendarFilter( new CalendarFilter() );
469 // Set the attributesOfInterest here if needed.
470 //std::string query ("SELECT " + calendarFilter.concatenateFilterAttributes() + " FROM schedule_table");
471 std::string query (std::string("SELECT ") + CAL_VALUE_INT_INDEX + " FROM schedule_table");
472 LogInfo("Default query statement: "<<query);
474 TizenApis::Api::Tizen::IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<TizenApis::Api::Tizen::IFilterVisitor>(calendarFilter);
476 if (event->getGenericFilterIsSet()) {
477 TizenApis::Api::Tizen::FilterPtr genericFilter = event->getGenericFilter();
479 TizenApis::Api::Tizen::FilterValidatorPtr validator = CalendarFilterValidatorFactory::getCalendarFilterValidator();
480 bool success = genericFilter->validate(validator);
482 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
484 LogInfo("Filter validation has passed.");
487 genericFilter->travel(filterTraversal, 0);
488 LogDebug("Traverse string [" << calendarFilter->getResult() << "]");
489 query.append(calendarFilter->getResult());
490 query.append(" AND is_deleted = 0;");
492 query.append(" WHERE is_deleted = 0;");
495 if (event->getSortModesIsSet()) {
496 query.append(calendarFilter->makeQuerySortMode(event->getSortModes()));
499 LogDebug("Filter query [" << query << "]");
501 calendarFilter->executeQuery(query, event->getEvents());
503 LogDebug("Result count [" << event->getEvents()->size() << "]");
507 // Now load the full calendar item using the retrieved id.
508 for( unsigned int i=0; i<event->getEvents()->size(); i++) {
509 // platformEvent is freed when the wrapper destructor is called.
510 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvents()->at(i), getType()));
511 eventWrapper->loadEvent(event->getEvents()->at(i)->getId());
514 catch (const InvalidArgumentException &ex)
516 LogError("Exception: " << ex.DumpToString());
517 event->setResult(false);
518 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
520 catch (const NotFoundException &ex)
522 LogError("Exception: " << ex.DumpToString());
523 event->setResult(false);
524 event->setExceptionCode(ExceptionCodes::NotFoundException);
526 catch (const Exception &ex)
528 LogError("Exception: " << ex.DumpToString());
529 event->setResult(false);
530 event->setExceptionCode(ExceptionCodes::UnknownException);
536 cal_iter *iter = NULL;
539 const EventFilterPtr filter = event->getFilter();
540 cal_struct *platformEvent = NULL;
541 bool isStartDateSet = false;
545 LogInfo("Filter is not set.");
546 const char *dataType;
547 if(getType() == CalendarEvent::TASK_TYPE) {
548 dataType = CAL_STRUCT_TODO;
550 dataType = CAL_STRUCT_SCHEDULE;
553 std::istringstream stream(getId());
556 if (CAL_SUCCESS != calendar_svc_get_all(getAccountId(), calendarId, dataType, &iter)) {
557 ThrowMsg(PlatformException, "Can't get all records");
561 // Use the new calendar service search function with multiple type/value pairs.
564 const char *searchType[9];
565 const void *searchValue[9];
567 if(filter->getIdIsSet()) {
568 // Platform supports integer type db index only.
569 std::istringstream istream(filter->getIdFilter());
572 searchType[filterCount] = CAL_VALUE_INT_INDEX;
573 searchValue[filterCount++] = (void*)(id);
575 if(filter->getSubjectIsSet()) {
576 searchType[filterCount] = CAL_VALUE_TXT_SUMMARY;
577 searchValue[filterCount++] = (void*)(filter->getSubjectFilter().c_str());
579 if(filter->getDescriptionIsSet()) {
580 searchType[filterCount] = CAL_VALUE_TXT_DESCRIPTION;
581 searchValue[filterCount++] = (void*)(filter->getDescriptionFilter().c_str());
583 if(filter->getLocationIsSet()) {
584 searchType[filterCount] = CAL_VALUE_TXT_LOCATION;
585 searchValue[filterCount++] = (void*)(filter->getLocationFilter().c_str());
587 if(filter->getCategoryIsSet()) {
588 searchType[filterCount] = CAL_VALUE_TXT_MEETING_CATEGORY_DETAIL_NAME;
589 searchValue[filterCount++] = (void*)(filter->getCategoryFilter().c_str());
591 if(filter->getStatusIsSet()) {
592 std::stringstream ss;
594 for( unsigned int i=0; i<filter->getStatusFilter().size(); i++ ) {
595 cal_status_type_t statusValue = CAL_STATUS_CONFIRM;
596 switch(filter->getStatusFilter().at(i)) {
597 case CalendarEvent::TENTATIVE_STATUS:
598 statusValue = CAL_STATUS_TENTATIVE;
600 case CalendarEvent::CANCELLED_STATUS:
601 statusValue = CAL_STATUS_DENIED;
603 case CalendarEvent::CONFIRMED_STATUS:
605 statusValue = CAL_STATUS_CONFIRM;
610 searchType[filterCount] = CAL_VALUE_INT_MEETING_STATUS;
612 searchValue[filterCount++] = (void*)(status.c_str());
613 LogInfo("status filter "<<status.c_str());
615 if(filter->getStartTimeMinIsSet()) {
616 searchType[filterCount] = CAL_VALUE_GMT_START_DATE_TIME;
617 searchValue[filterCount++] = (void*)(filter->getStartTimeMinFilter());
618 isStartDateSet = true;
620 if(filter->getStartTimeMaxIsSet()) {
621 searchType[filterCount] = CAL_VALUE_GMT_END_DATE_TIME;
622 searchValue[filterCount++] = (void*)(filter->getStartTimeMaxFilter());
623 isStartDateSet = true;
625 LogInfo("Filter is set: "<<filterCount);
628 calendar_svc_find_event_list_by_filter(0, filterCount, searchType, searchValue, &iter)) {
629 ThrowMsg(NotFoundException, "Can't find event list by filter.");
633 while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
634 event->tryCancelled();
636 platformEvent = NULL;
638 calendar_svc_iter_get_info(iter, &platformEvent)) {
639 ThrowMsg(PlatformException, "Can't get event info.");
642 // platformEvent is freed when the wrapper destructor is called.
643 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(platformEvent, getType()));
645 eventWrapper->convertPlatformEventToAbstractEvent()->setCalendarType(getType());
646 event->addEvent(eventWrapper->getAbstractEvent());
649 // Process the recurring event cases here.
650 if ( isStartDateSet ) {
651 LogInfo("Process the recurring evets");
653 calendar_svc_find_recurring_event_list(0, &iter)) {
654 ThrowMsg(PlatformException, "Can't find recurring event list.");
657 time_t startTime, endTime, nextStartTime, nextEndTime;
658 if (filter->getStartTimeMinIsSet()) {
659 startTime = filter->getStartTimeMinFilter();
663 if (filter->getStartTimeMaxIsSet()) {
664 endTime = filter->getStartTimeMaxFilter();
666 endTime = INT_MAX; // about 60 years in 4 bytes system.
669 while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
670 event->tryCancelled();
672 nextStartTime = 0; // It's important to reset this before calling calendar_svc_util_next_valid_event.
674 platformEvent = NULL;
676 calendar_svc_iter_get_info(iter, &platformEvent)) {
677 ThrowMsg(PlatformException, "Can't get event info.");
681 calendar_svc_util_next_valid_event(platformEvent, startTime, endTime, &nextStartTime, &nextEndTime) ) {
682 bool isDuplicated = false;
683 for( unsigned int i=0; i<event->getEvents()->size(); i++ ) {
684 if (calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX)==event->getEvents()->at(i)->getId())
688 LogInfo("Found a recurring event inbetween the start time period.");
689 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(platformEvent, getType()));
690 eventWrapper->convertPlatformEventToAbstractEvent()->setCalendarType(getType());
691 event->addEvent(eventWrapper->getAbstractEvent());
697 catch (const NotFoundException &ex)
699 LogError("Exception: " << ex.DumpToString());
700 event->setResult(false);
701 event->setExceptionCode(ExceptionCodes::NotFoundException);
703 catch (const Exception &ex)
705 LogError("Exception: " << ex.DumpToString());
706 event->setResult(false);
707 event->setExceptionCode(ExceptionCodes::UnknownException);
710 calendar_svc_iter_remove(&iter);
714 void Calendar::OnRequestReceived(const IEventCreateEventPtr &event)
719 event->setEvent(CalendarEventPtr(new CalendarEvent()));
720 event->getEvent()->setCalendarType(getType());
721 event->setResult(event->getEvent().Get() != NULL);
723 catch (const Exception &ex)
725 LogError("Error during creating an event " << ex.DumpToString());
726 event->setResult(false);
727 event->setExceptionCode(ExceptionCodes::UnknownException);
731 void Calendar::OnRequestReceived(const IEventCreateEventFromStringPtr &event)
736 if (event->checkCancelled()) {
737 event->setCancelAllowed(true);
738 event->setResult(true);
742 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
743 eventWrapper->createEventFromString(event->getEventString());
744 event->setEvent(eventWrapper->convertPlatformEventToAbstractEvent());
745 event->getEvent()->setCalendarType(getType());
746 event->setResult(true);
748 catch (const Exception &ex)
750 LogError("Error during creating event from string" << ex.DumpToString());
751 LogInfo("eventString: " + event->getEventString());
752 event->setResult(false);
753 event->setExceptionCode(ExceptionCodes::UnknownException);
755 event->setCancelAllowed(false);
758 void Calendar::OnRequestReceived(const IEventExportEventToStringPtr &event)
763 if (!event->getEvent()) {
764 ThrowMsg(NullPointerException, "event parameter is NULL");
767 if (event->checkCancelled()) {
768 event->setCancelAllowed(true);
769 event->setResult(true);
773 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
774 event->getEvent()->setCalendarType(getType());
775 eventWrapper->convertAbstractEventToPlatformEvent();
776 event->setEventString(eventWrapper->exportEventToString());
777 event->setResult(true);
779 catch (const Exception &ex)
781 LogError("Error during creating string from event" << ex.DumpToString());
782 event->setResult(false);
783 event->setExceptionCode(ExceptionCodes::UnknownException);
785 event->setCancelAllowed(false);
788 static void eventChangedCb(void *user_data)
792 OnEventsChangedPtr eventPtr(new OnEventsChanged());
795 Calendar *thisCalendar = (Calendar*) user_data;
797 // Determine the status of event change.
798 cal_iter *iter = NULL;
799 cal_struct *platformEvent = NULL;
803 if( CAL_SUCCESS != calendar_svc_get_updated_event_list(thisCalendar->getAccountId(),
804 thisCalendar->getLastChangeFetchTime(),
806 ThrowMsg(PlatformException, "Can't get the updated event list.");
808 while( CAL_SUCCESS == calendar_svc_iter_next(iter) )
810 if ( CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent) ) {
811 ThrowMsg(PlatformException, "Can't get the calendar info.");
814 index = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
815 syncStatus = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_SYNC_STATUS);
816 LogDebug("index "<<index<<" , syncStatus "<<syncStatus);
817 if ( CAL_SYNC_STATUS_NEW==syncStatus ) {
818 eventPtr->setStatus(OnEventsChanged::ON_ADD);
819 } else if ( CAL_SYNC_STATUS_UPDATED==syncStatus ) {
820 eventPtr->setStatus(OnEventsChanged::ON_UPDATE);
821 } else if ( CAL_SYNC_STATUS_DELETED==syncStatus ) {
822 eventPtr->setStatus(OnEventsChanged::ON_DELETE);
824 if( platformEvent ) {
825 calendar_svc_struct_free(&platformEvent);
827 calendar_svc_iter_remove(&iter);
828 ThrowMsg(PlatformException, "Wrong syncStatus.");
831 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisCalendar->getType()));
832 eventWrapper->loadEvent(index);
833 eventPtr->addEvent(eventWrapper->getAbstractEvent());
835 if ( CAL_SUCCESS != calendar_svc_struct_free(&platformEvent) ) {
836 ThrowMsg(PlatformException, "Can't free the platform event struct.");
840 if ( CAL_SUCCESS != calendar_svc_iter_remove(&iter) ) {
841 ThrowMsg(PlatformException, "Can't remove the iter.");
844 std::time_t localTime = time(NULL);
845 thisCalendar->setLastChangeFetchTime(localTime);
846 LogInfo("Last change fetch time: "<<thisCalendar->getLastChangeFetchTime());
848 eventPtr->setResult(true);
850 if( eventPtr->getEventList()->size() > 0 ) {
851 thisCalendar->m_changeEmitters.emit(eventPtr);
853 LogInfo("No actual changes. Skip signal emission.");
856 catch (const Exception &ex)
858 LogError("Error while emitting the change noti" << ex.DumpToString());
862 void Calendar::OnRequestReceived(const IEventWatchChangesPtr &event)
867 // Subscribe the watch to the platform just once.
868 if( m_changeEmitters.size()==0 )
870 if( CAL_SUCCESS!=calendar_svc_subscribe_change(eventChangedCb, this) ) {
871 ThrowMsg(PlatformException, "Can't subscribe the db change noti.");
873 // Save the last change fetch time to start watching.
874 std::time_t localTime = time(NULL);
875 setLastChangeFetchTime(localTime);
876 LogInfo("Last change fetch time: "<<getLastChangeFetchTime());
880 m_changeEmitters.attach(event->getEmitter());
881 event->setWatchId(event->getEmitter()->getId());
882 event->setResult(true);
884 catch (const Exception &ex)
886 LogError("Error during creating a watch " << ex.DumpToString());
887 event->setResult(false);
888 event->setExceptionCode(ExceptionCodes::UnknownException);
892 void Calendar::OnRequestReceived(const IEventClearWatchPtr &event)
897 m_changeEmitters.detach(event->getWatchId());
899 if( m_changeEmitters.size()==0 ) {
900 if( CAL_SUCCESS!=calendar_svc_unsubscribe_change(eventChangedCb) ) {
901 ThrowMsg(PlatformException, "Can't unsubscribe the db change noti.");
903 LogDebug("Platform watch cleared successfully.");
906 event->setResult(true);
908 catch (const Exception &ex)
910 LogError("Error during clearing the watch " << ex.DumpToString());
911 event->setResult(false);
912 event->setExceptionCode(ExceptionCodes::UnknownException);
916 void Calendar::OnRequestReceived(const IEventExpandEventRecurrencePtr &event)
919 const CalendarEventPtr calEvent = event->getEvent();
920 const time_t startDate = event->getStartDate();
921 const time_t endDate = event->getEndDate();
922 event->setResult(true);
925 if ( 0 >= calEvent->getRecurrenceRule()->getFrequency())
927 ThrowMsg(PlatformException, "This is not a recurring event.");
930 std::time_t nextStartTime = 0;
931 std::time_t nextEndTime = 0;
933 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
934 eventWrapper->convertAbstractEventToPlatformEvent();
936 event->tryCancelled();
938 while ( CAL_SUCCESS ==
939 calendar_svc_util_next_valid_event(eventWrapper->getPlatformEvent(), startDate, endDate, &nextStartTime, &nextEndTime) ) {
940 LogInfo("Found a next vaild event: "<<nextStartTime);
941 DPL::ScopedPtr<EventWrapper> recurringEventWrapper(new EventWrapper(getType()));
942 recurringEventWrapper->loadEvent(calEvent->getId());
943 recurringEventWrapper->getAbstractEvent()->setRecurrenceId(nextStartTime);
944 event->addExpandedEvent(recurringEventWrapper->getAbstractEvent());
947 LogInfo("Length of expanded events: "<<event->getExpandedEventList()->size());
949 catch (const Exception &ex)
951 LogError("Exception: " << ex.DumpToString());
952 event->setResult(false);
953 event->setExceptionCode(ExceptionCodes::UnknownException);
956 event->setCancelAllowed(true);