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 std::stringstream ssType;
477 std::stringstream ssAccount;
478 ssAccount<<getAccountId();
479 if (event->getGenericFilterIsSet()) {
480 TizenApis::Api::Tizen::FilterPtr genericFilter = event->getGenericFilter();
482 TizenApis::Api::Tizen::FilterValidatorPtr validator = CalendarFilterValidatorFactory::getCalendarFilterValidator();
483 bool success = genericFilter->validate(validator);
485 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
487 LogInfo("Filter validation has passed.");
490 genericFilter->travel(filterTraversal, 0);
491 LogDebug("Traverse string [" << calendarFilter->getResult() << "]");
492 query.append(calendarFilter->getResult());
493 query.append(std::string(" AND ") + CAL_VALUE_INT_ACCOUNT_ID + " = " + ssAccount.str());
494 if (getType()==CalendarEvent::TASK_TYPE) {
495 ssType<<CALS_CALENDAR_TYPE_TODO;
496 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0;");
498 ssType<<CALS_CALENDAR_TYPE_EVENT;
499 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0;");
502 query.append(std::string(" WHERE ") + CAL_VALUE_INT_ACCOUNT_ID + " = " + ssAccount.str());
503 if (getType()==CalendarEvent::TASK_TYPE) {
504 ssType<<CALS_CALENDAR_TYPE_TODO;
505 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0;");
507 ssType<<CALS_CALENDAR_TYPE_EVENT;
508 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0;");
512 if (event->getSortModesIsSet()) {
513 query.append(calendarFilter->makeQuerySortMode(event->getSortModes()));
516 LogDebug("Filter query [" << query << "]");
518 calendarFilter->executeQuery(query, event->getEvents());
520 LogDebug("Result count [" << event->getEvents()->size() << "]");
524 // Now load the full calendar item using the retrieved id.
525 for( unsigned int i=0; i<event->getEvents()->size(); i++) {
526 // platformEvent is freed when the wrapper destructor is called.
527 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvents()->at(i), getType()));
528 eventWrapper->loadEvent(event->getEvents()->at(i)->getId());
531 catch (const InvalidArgumentException &ex)
533 LogError("Exception: " << ex.DumpToString());
534 event->setResult(false);
535 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
537 catch (const NotFoundException &ex)
539 LogError("Exception: " << ex.DumpToString());
540 event->setResult(false);
541 event->setExceptionCode(ExceptionCodes::NotFoundException);
543 catch (const Exception &ex)
545 LogError("Exception: " << ex.DumpToString());
546 event->setResult(false);
547 event->setExceptionCode(ExceptionCodes::UnknownException);
553 cal_iter *iter = NULL;
556 const EventFilterPtr filter = event->getFilter();
557 cal_struct *platformEvent = NULL;
558 bool isStartDateSet = false;
562 LogInfo("Filter is not set.");
563 const char *dataType;
564 if(getType() == CalendarEvent::TASK_TYPE) {
565 dataType = CAL_STRUCT_TODO;
567 dataType = CAL_STRUCT_SCHEDULE;
570 std::istringstream stream(getId());
573 if (CAL_SUCCESS != calendar_svc_get_all(getAccountId(), calendarId, dataType, &iter)) {
574 ThrowMsg(PlatformException, "Can't get all records");
578 // Use the new calendar service search function with multiple type/value pairs.
581 const char *searchType[9];
582 const void *searchValue[9];
584 if(filter->getIdIsSet()) {
585 // Platform supports integer type db index only.
586 std::istringstream istream(filter->getIdFilter());
589 searchType[filterCount] = CAL_VALUE_INT_INDEX;
590 searchValue[filterCount++] = (void*)(id);
592 if(filter->getSubjectIsSet()) {
593 searchType[filterCount] = CAL_VALUE_TXT_SUMMARY;
594 searchValue[filterCount++] = (void*)(filter->getSubjectFilter().c_str());
596 if(filter->getDescriptionIsSet()) {
597 searchType[filterCount] = CAL_VALUE_TXT_DESCRIPTION;
598 searchValue[filterCount++] = (void*)(filter->getDescriptionFilter().c_str());
600 if(filter->getLocationIsSet()) {
601 searchType[filterCount] = CAL_VALUE_TXT_LOCATION;
602 searchValue[filterCount++] = (void*)(filter->getLocationFilter().c_str());
604 if(filter->getCategoryIsSet()) {
605 searchType[filterCount] = CAL_VALUE_TXT_MEETING_CATEGORY_DETAIL_NAME;
606 searchValue[filterCount++] = (void*)(filter->getCategoryFilter().c_str());
608 if(filter->getStatusIsSet()) {
609 std::stringstream ss;
611 for( unsigned int i=0; i<filter->getStatusFilter().size(); i++ ) {
612 cal_status_type_t statusValue = CAL_STATUS_CONFIRM;
613 switch(filter->getStatusFilter().at(i)) {
614 case CalendarEvent::TENTATIVE_STATUS:
615 statusValue = CAL_STATUS_TENTATIVE;
617 case CalendarEvent::CANCELLED_STATUS:
618 statusValue = CAL_STATUS_DENIED;
620 case CalendarEvent::CONFIRMED_STATUS:
622 statusValue = CAL_STATUS_CONFIRM;
627 searchType[filterCount] = CAL_VALUE_INT_MEETING_STATUS;
629 searchValue[filterCount++] = (void*)(status.c_str());
630 LogInfo("status filter "<<status.c_str());
632 if(filter->getStartTimeMinIsSet()) {
633 searchType[filterCount] = CAL_VALUE_GMT_START_DATE_TIME;
634 searchValue[filterCount++] = (void*)(filter->getStartTimeMinFilter());
635 isStartDateSet = true;
637 if(filter->getStartTimeMaxIsSet()) {
638 searchType[filterCount] = CAL_VALUE_GMT_END_DATE_TIME;
639 searchValue[filterCount++] = (void*)(filter->getStartTimeMaxFilter());
640 isStartDateSet = true;
642 LogInfo("Filter is set: "<<filterCount);
645 calendar_svc_find_event_list_by_filter(0, filterCount, searchType, searchValue, &iter)) {
646 ThrowMsg(NotFoundException, "Can't find event list by filter.");
650 while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
651 event->tryCancelled();
653 platformEvent = NULL;
655 calendar_svc_iter_get_info(iter, &platformEvent)) {
656 ThrowMsg(PlatformException, "Can't get event info.");
659 // platformEvent is freed when the wrapper destructor is called.
660 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(platformEvent, getType()));
662 eventWrapper->convertPlatformEventToAbstractEvent()->setCalendarType(getType());
663 event->addEvent(eventWrapper->getAbstractEvent());
666 // Process the recurring event cases here.
667 if ( isStartDateSet ) {
668 LogInfo("Process the recurring evets");
670 calendar_svc_find_recurring_event_list(0, &iter)) {
671 ThrowMsg(PlatformException, "Can't find recurring event list.");
674 time_t startTime, endTime, nextStartTime, nextEndTime;
675 if (filter->getStartTimeMinIsSet()) {
676 startTime = filter->getStartTimeMinFilter();
680 if (filter->getStartTimeMaxIsSet()) {
681 endTime = filter->getStartTimeMaxFilter();
683 endTime = INT_MAX; // about 60 years in 4 bytes system.
686 while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
687 event->tryCancelled();
689 nextStartTime = 0; // It's important to reset this before calling calendar_svc_util_next_valid_event.
691 platformEvent = NULL;
693 calendar_svc_iter_get_info(iter, &platformEvent)) {
694 ThrowMsg(PlatformException, "Can't get event info.");
698 calendar_svc_util_next_valid_event(platformEvent, startTime, endTime, &nextStartTime, &nextEndTime) ) {
699 bool isDuplicated = false;
700 for( unsigned int i=0; i<event->getEvents()->size(); i++ ) {
701 if (calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX)==event->getEvents()->at(i)->getId())
705 LogInfo("Found a recurring event inbetween the start time period.");
706 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(platformEvent, getType()));
707 eventWrapper->convertPlatformEventToAbstractEvent()->setCalendarType(getType());
708 event->addEvent(eventWrapper->getAbstractEvent());
714 catch (const NotFoundException &ex)
716 LogError("Exception: " << ex.DumpToString());
717 event->setResult(false);
718 event->setExceptionCode(ExceptionCodes::NotFoundException);
720 catch (const Exception &ex)
722 LogError("Exception: " << ex.DumpToString());
723 event->setResult(false);
724 event->setExceptionCode(ExceptionCodes::UnknownException);
727 calendar_svc_iter_remove(&iter);
731 void Calendar::OnRequestReceived(const IEventCreateEventPtr &event)
736 event->setEvent(CalendarEventPtr(new CalendarEvent()));
737 event->getEvent()->setCalendarType(getType());
738 event->setResult(event->getEvent().Get() != NULL);
740 catch (const Exception &ex)
742 LogError("Error during creating an event " << ex.DumpToString());
743 event->setResult(false);
744 event->setExceptionCode(ExceptionCodes::UnknownException);
748 void Calendar::OnRequestReceived(const IEventCreateEventFromStringPtr &event)
753 if (event->checkCancelled()) {
754 event->setCancelAllowed(true);
755 event->setResult(true);
759 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
760 eventWrapper->createEventFromString(event->getEventString());
761 event->setEvent(eventWrapper->convertPlatformEventToAbstractEvent());
762 event->getEvent()->setCalendarType(getType());
763 event->setResult(true);
765 catch (const Exception &ex)
767 LogError("Error during creating event from string" << ex.DumpToString());
768 LogInfo("eventString: " + event->getEventString());
769 event->setResult(false);
770 event->setExceptionCode(ExceptionCodes::UnknownException);
772 event->setCancelAllowed(false);
775 void Calendar::OnRequestReceived(const IEventExportEventToStringPtr &event)
780 if (!event->getEvent()) {
781 ThrowMsg(NullPointerException, "event parameter is NULL");
784 if (event->checkCancelled()) {
785 event->setCancelAllowed(true);
786 event->setResult(true);
790 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
791 event->getEvent()->setCalendarType(getType());
792 eventWrapper->convertAbstractEventToPlatformEvent();
793 event->setEventString(eventWrapper->exportEventToString());
794 event->setResult(true);
796 catch (const Exception &ex)
798 LogError("Error during creating string from event" << ex.DumpToString());
799 event->setResult(false);
800 event->setExceptionCode(ExceptionCodes::UnknownException);
802 event->setCancelAllowed(false);
805 static void eventChangedCb(void *user_data)
809 OnEventsChangedPtr eventPtr(new OnEventsChanged());
812 Calendar *thisCalendar = (Calendar*) user_data;
814 // Determine the status of event change.
815 cal_iter *iter = NULL;
816 cal_struct *platformEvent = NULL;
820 if( CAL_SUCCESS != calendar_svc_get_updated_event_list(thisCalendar->getAccountId(),
821 thisCalendar->getLastChangeFetchTime(),
823 ThrowMsg(PlatformException, "Can't get the updated event list.");
825 while( CAL_SUCCESS == calendar_svc_iter_next(iter) )
827 if ( CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent) ) {
828 ThrowMsg(PlatformException, "Can't get the calendar info.");
831 index = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
832 syncStatus = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_SYNC_STATUS);
833 LogDebug("index "<<index<<" , syncStatus "<<syncStatus);
834 if ( CAL_SYNC_STATUS_NEW==syncStatus ) {
835 eventPtr->setStatus(OnEventsChanged::ON_ADD);
836 } else if ( CAL_SYNC_STATUS_UPDATED==syncStatus ) {
837 eventPtr->setStatus(OnEventsChanged::ON_UPDATE);
838 } else if ( CAL_SYNC_STATUS_DELETED==syncStatus ) {
839 eventPtr->setStatus(OnEventsChanged::ON_DELETE);
841 if( platformEvent ) {
842 calendar_svc_struct_free(&platformEvent);
844 calendar_svc_iter_remove(&iter);
845 ThrowMsg(PlatformException, "Wrong syncStatus.");
848 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisCalendar->getType()));
849 eventWrapper->loadEvent(index);
850 eventPtr->addEvent(eventWrapper->getAbstractEvent());
852 if ( CAL_SUCCESS != calendar_svc_struct_free(&platformEvent) ) {
853 ThrowMsg(PlatformException, "Can't free the platform event struct.");
857 if ( CAL_SUCCESS != calendar_svc_iter_remove(&iter) ) {
858 ThrowMsg(PlatformException, "Can't remove the iter.");
861 std::time_t localTime = time(NULL);
862 thisCalendar->setLastChangeFetchTime(localTime);
863 LogInfo("Last change fetch time: "<<thisCalendar->getLastChangeFetchTime());
865 eventPtr->setResult(true);
867 if( eventPtr->getEventList()->size() > 0 ) {
868 thisCalendar->m_changeEmitters.emit(eventPtr);
870 LogInfo("No actual changes. Skip signal emission.");
873 catch (const Exception &ex)
875 LogError("Error while emitting the change noti" << ex.DumpToString());
879 void Calendar::OnRequestReceived(const IEventWatchChangesPtr &event)
884 // Subscribe the watch to the platform just once.
885 if( m_changeEmitters.size()==0 )
887 if( CAL_SUCCESS!=calendar_svc_subscribe_change(eventChangedCb, this) ) {
888 ThrowMsg(PlatformException, "Can't subscribe the db change noti.");
890 // Save the last change fetch time to start watching.
891 std::time_t localTime = time(NULL);
892 setLastChangeFetchTime(localTime);
893 LogInfo("Last change fetch time: "<<getLastChangeFetchTime());
897 m_changeEmitters.attach(event->getEmitter());
898 event->setWatchId(event->getEmitter()->getId());
899 event->setResult(true);
901 catch (const Exception &ex)
903 LogError("Error during creating a watch " << ex.DumpToString());
904 event->setResult(false);
905 event->setExceptionCode(ExceptionCodes::UnknownException);
909 void Calendar::OnRequestReceived(const IEventClearWatchPtr &event)
914 m_changeEmitters.detach(event->getWatchId());
916 if( m_changeEmitters.size()==0 ) {
917 if( CAL_SUCCESS!=calendar_svc_unsubscribe_change(eventChangedCb) ) {
918 ThrowMsg(PlatformException, "Can't unsubscribe the db change noti.");
920 LogDebug("Platform watch cleared successfully.");
923 event->setResult(true);
925 catch (const Exception &ex)
927 LogError("Error during clearing the watch " << ex.DumpToString());
928 event->setResult(false);
929 event->setExceptionCode(ExceptionCodes::UnknownException);
933 void Calendar::OnRequestReceived(const IEventExpandEventRecurrencePtr &event)
936 const CalendarEventPtr calEvent = event->getEvent();
937 const time_t startDate = event->getStartDate();
938 const time_t endDate = event->getEndDate();
939 event->setResult(true);
942 if ( 0 >= calEvent->getRecurrenceRule()->getFrequency())
944 ThrowMsg(PlatformException, "This is not a recurring event.");
947 std::time_t nextStartTime = 0;
948 std::time_t nextEndTime = 0;
950 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
951 eventWrapper->convertAbstractEventToPlatformEvent();
953 event->tryCancelled();
955 while ( CAL_SUCCESS ==
956 calendar_svc_util_next_valid_event(eventWrapper->getPlatformEvent(), startDate, endDate, &nextStartTime, &nextEndTime) ) {
957 LogInfo("Found a next vaild event: "<<nextStartTime);
958 DPL::ScopedPtr<EventWrapper> recurringEventWrapper(new EventWrapper(getType()));
959 recurringEventWrapper->loadEvent(calEvent->getId());
960 recurringEventWrapper->getAbstractEvent()->setRecurrenceId(nextStartTime);
961 event->addExpandedEvent(recurringEventWrapper->getAbstractEvent());
964 LogInfo("Length of expanded events: "<<event->getExpandedEventList()->size());
966 catch (const Exception &ex)
968 LogError("Exception: " << ex.DumpToString());
969 event->setResult(false);
970 event->setExceptionCode(ExceptionCodes::UnknownException);
973 event->setCancelAllowed(true);