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/OnEventsChanged.h"
27 #include "API/Calendar/IEventWatchChanges.h"
28 #include "API/Calendar/IEventClearWatch.h"
29 #include "API/Calendar/EventId.h"
30 #include <API/Filter/IFilter.h>
31 #include <API/Filter/IFilterVisitor.h>
34 using namespace TizenApis::Api::Calendar;
35 using namespace WrtDeviceApis::Commons;
51 void Calendar::OnRequestReceived(const IEventAddEventPtr &event)
56 if (!event->getEvent()) {
57 ThrowMsg(NullPointerException, "event parameter is NULL");
59 if (event->getEvent()->getIdIsSet()) {
60 LogWarning("adding event that is already added");
61 event->getEvent()->resetId();
63 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
64 event->getEvent()->setCalendarType(getType());
65 eventWrapper->convertAbstractEventToPlatformEvent();
67 // Set the account and calendar id before saving the item.
68 eventWrapper->setCalendarId(getId());
69 eventWrapper->setCalendarAccountId(getAccountId());
70 eventWrapper->saveEvent();
71 event->setResult(true);
75 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
76 event->setResult(false);
77 event->setExceptionCode(ExceptionCodes::UnknownException);
81 void Calendar::OnRequestReceived(const IEventAddEventsPtr &events)
87 if (events->getEvents()->empty()) {
88 ThrowMsg(NullPointerException, "Items array is empty.");
91 int returnValue = calendar_svc_begin_trans();
92 if(CAL_SUCCESS!=returnValue) {
93 ThrowMsg(PlatformException, "Begin transaction failed with error code: "<<returnValue);
95 LogInfo("Begin transaction succeeded.");
98 bool failedAdding = false;
99 for(unsigned int i=0; i<events->getEvents()->size(); i++)
101 if (events->getEvents()->at(i)->getIdIsSet()) {
102 LogWarning("Item has index: " << i << ". Resetting it.");
103 events->getEvents()->at(i)->resetId();
105 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(events->getEvents()->at(i), getType()));
106 events->getEvents()->at(i)->setCalendarType(getType());
107 eventWrapper->convertAbstractEventToPlatformEvent();
110 eventWrapper->setCalendarId(getId());
111 eventWrapper->setCalendarAccountId(getAccountId());
112 eventWrapper->saveEvent();
113 } Catch (Exception) {
114 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
119 if( false==failedAdding ) {
120 events->setResult(true);
122 returnValue = calendar_svc_end_trans(true);
123 LogInfo("End transaction return value with true flag: "<<returnValue);
125 events->setResult(false);
127 returnValue = calendar_svc_end_trans(false);
128 LogInfo("End transaction return value with false flag: "<<returnValue);
133 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
134 events->setResult(false);
135 events->setExceptionCode(ExceptionCodes::UnknownException);
139 void Calendar::OnRequestReceived(const IEventUpdateEventPtr &event)
143 cal_iter *iter = NULL;
146 if (!event->getEvent()) {
147 ThrowMsg(NullPointerException, "Item object is NULL.");
149 if (!event->getEvent()->getIdIsSet()) {
150 ThrowMsg(InvalidArgumentException, "Item id is not set.");
153 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
154 event->getEvent()->setCalendarType(getType());
155 eventWrapper->convertAbstractEventToPlatformEvent();
157 if ( event->getUpdateAllInstances() || 0>=event->getEvent()->getRecurrenceRule()->getFrequency())
159 // Update all parent and child instances with the given uid.
160 int parentId = event->getEvent()->getId();
162 // First, the parent event.
163 eventWrapper->saveEvent();
165 // Next, all the detached instances.
166 cal_struct *platformEvent = NULL;
167 if(CAL_SUCCESS != calendar_svc_find_event_list(getAccountId(), CAL_VALUE_INT_ORIGINAL_EVENT_ID, (void*) parentId, &iter)) {
168 LogInfo("No detached instances found.");
171 while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
172 platformEvent = NULL;
173 if (CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent)) {
174 ThrowMsg(PlatformException, "Can't get event info.");
177 int detachedEventId = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
178 long long int detachedStartTime = calendar_svc_struct_get_lli(platformEvent, CALS_VALUE_LLI_DTSTART_UTIME);
179 long long int detachedEndTime = calendar_svc_struct_get_lli(platformEvent, CALS_VALUE_LLI_DTEND_UTIME);
181 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(event->getEvent(), getType()));
182 eventWrapperChild->convertAbstractEventToPlatformEvent();
183 if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
186 ThrowMsg(PlatformException, "Can't set event Id.");
188 if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
189 CAL_VALUE_INT_ORIGINAL_EVENT_ID,
191 ThrowMsg(PlatformException, "Can't set parent Id.");
193 if (CAL_SUCCESS != calendar_svc_struct_set_lli(eventWrapperChild->getPlatformEvent(),
194 CALS_VALUE_LLI_DTSTART_UTIME,
195 detachedStartTime)) {
196 ThrowMsg(PlatformException, "Can't set start time.");
198 if (CAL_SUCCESS != calendar_svc_struct_set_lli(eventWrapperChild->getPlatformEvent(),
199 CALS_VALUE_LLI_DTEND_UTIME,
201 ThrowMsg(PlatformException, "Can't set end time.");
203 if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
204 CALS_VALUE_INT_RRULE_FREQ,
206 ThrowMsg(PlatformException, "Can't set repeat term.");
209 eventWrapperChild->saveEvent();
210 LogDebug("Updated a detached event by id: "<<detachedEventId);
215 LogDebug("Update the exception record");
216 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(event->getEvent(), getType()));
217 eventWrapperChild->convertAbstractEventToPlatformEvent();
218 if ( CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
219 CAL_VALUE_INT_ORIGINAL_EVENT_ID, event->getEvent()->getId()) ) {
220 ThrowMsg(PlatformException, "cannot save exception event");
222 // Use "CAL_VALUE_LLI_COMPLETED_TIME" as the recurrence id saving point.
223 if ( CAL_SUCCESS!=calendar_svc_struct_set_lli(eventWrapperChild->getPlatformEvent(),
224 CAL_VALUE_LLI_COMPLETED_TIME, event->getEvent()->getRecurrenceId()) ) {
225 ThrowMsg(PlatformException, "cannot save recurrence id");
227 LogInfo("Saved the rid for the child: "<<event->getEvent()->getRecurrenceId());
229 if (CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
230 CALS_VALUE_INT_RRULE_FREQ, CAL_REPEAT_NONE) ) {
231 ThrowMsg(PlatformException, "cannot save exception event");
233 int childId = calendar_svc_insert(eventWrapperChild->getPlatformEvent());
235 ThrowMsg(PlatformException, "cannot save exception event");
238 int error = calendar_svc_event_delete_normal_instance(event->getEvent()->getId(), event->getEvent()->getRecurrenceId());
239 if(error!=CAL_SUCCESS) {
240 ThrowMsg(PlatformException, "Can't delete the instance. Error code " << error);
243 event->getEvent()->setIsDetached(true);
246 event->setResult(true);
250 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
251 event->setResult(false);
252 event->setExceptionCode(ExceptionCodes::UnknownException);
256 calendar_svc_iter_remove(&iter);
260 void Calendar::OnRequestReceived(const IEventUpdateEventsPtr &events)
264 cal_iter *iter = NULL;
267 if (events->getEvents()->empty()) {
268 ThrowMsg(NullPointerException, "Item array is empty.");
271 int returnValue = calendar_svc_begin_trans();
272 if(CAL_SUCCESS!=returnValue) {
273 ThrowMsg(PlatformException, "Begin transaction failed with error code: "<<returnValue);
275 LogInfo("Begin transaction succeeded.");
278 bool failedUpdating = false;
279 for(unsigned int i=0; i<events->getEvents()->size(); i++)
281 CalendarEventPtr thisEvent = events->getEvents()->at(i);
282 if (!thisEvent->getIdIsSet()) {
283 ThrowMsg(InvalidArgumentException, "Item id is not set.");
285 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisEvent, getType()));
286 events->getEvents()->at(i)->setCalendarType(getType());
287 eventWrapper->convertAbstractEventToPlatformEvent();
290 if (events->getUpdateAllInstances() || 0>=thisEvent->getRecurrenceRule()->getFrequency())
292 // Update all parent and child instances with the given uid.
293 int parentId = thisEvent->getId();
295 // First, the parent event.
296 eventWrapper->saveEvent();
298 // Next, all the detached instances.
299 cal_struct *platformEvent = NULL;
300 if(CAL_SUCCESS != calendar_svc_find_event_list(getAccountId(), CAL_VALUE_INT_ORIGINAL_EVENT_ID, (void*) parentId, &iter)) {
301 LogInfo("No detached instances found.");
304 while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
305 platformEvent = NULL;
306 if (CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent)) {
307 ThrowMsg(PlatformException, "Can't get event info.");
310 int detachedEventId = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
311 long long int detachedStartTime = calendar_svc_struct_get_lli(platformEvent,
312 CALS_VALUE_LLI_DTSTART_UTIME);
313 long long int detachedEndTime = calendar_svc_struct_get_lli(platformEvent,
314 CALS_VALUE_LLI_DTEND_UTIME);
316 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(thisEvent, getType()));
317 eventWrapperChild->convertAbstractEventToPlatformEvent();
318 if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
321 ThrowMsg(PlatformException, "Can't set event Id.");
323 if (CAL_SUCCESS != calendar_svc_struct_set_lli(eventWrapperChild->getPlatformEvent(),
324 CALS_VALUE_LLI_DTSTART_UTIME,
325 detachedStartTime)) {
326 ThrowMsg(PlatformException, "Can't set start time.");
328 if (CAL_SUCCESS != calendar_svc_struct_set_lli(eventWrapperChild->getPlatformEvent(),
329 CALS_VALUE_LLI_DTEND_UTIME,
331 ThrowMsg(PlatformException, "Can't set end time.");
334 eventWrapper->saveEvent();
335 LogDebug("Updated a detached event by id: "<<detachedEventId);
340 LogDebug("Update the exception record");
341 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(thisEvent, getType()));
342 eventWrapperChild->convertAbstractEventToPlatformEvent();
344 if ( CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
345 CAL_VALUE_INT_ORIGINAL_EVENT_ID, thisEvent->getId()) ) {
346 ThrowMsg(PlatformException, "cannot save parent id.");
348 // Use "CAL_VALUE_LLI_COMPLETED_TIME" as the recurrence id saving point.
349 if ( CAL_SUCCESS!=calendar_svc_struct_set_lli(eventWrapperChild->getPlatformEvent(),
350 CAL_VALUE_LLI_COMPLETED_TIME, thisEvent->getRecurrenceId()) ) {
351 ThrowMsg(PlatformException, "cannot save recurrence id.");
353 LogInfo("Saved the rid for the child: "<<thisEvent->getRecurrenceId());
355 if (CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
356 CALS_VALUE_INT_RRULE_FREQ, CAL_REPEAT_NONE) ) {
357 ThrowMsg(PlatformException, "cannot save repeat term.");
359 int childId = calendar_svc_insert(eventWrapperChild->getPlatformEvent());
361 ThrowMsg(PlatformException, "cannot save exception event");
364 int error = calendar_svc_event_delete_normal_instance(thisEvent->getId(), thisEvent->getRecurrenceId());
365 if(error!=CAL_SUCCESS) {
366 ThrowMsg(PlatformException, "Can't delete the instance. Error code " << error);
369 thisEvent->setIsDetached(true);
371 } Catch (Exception) {
372 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
373 failedUpdating = true;
375 //getUpdateEmitter()->emit(eventPtr);
378 if( false==failedUpdating ) {
379 events->setResult(true);
381 returnValue = calendar_svc_end_trans(true);
382 LogInfo("End transaction return value with true flag: "<<returnValue);
384 events->setResult(false);
386 returnValue = calendar_svc_end_trans(false);
387 LogInfo("End transaction return value with false flag: "<<returnValue);
392 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
393 events->setResult(false);
394 events->setExceptionCode(ExceptionCodes::UnknownException);
398 calendar_svc_iter_remove(&iter);
402 void Calendar::OnRequestReceived(const IEventDeleteEventPtr &event)
407 if (!event->getEventId()) {
408 ThrowMsg(NullPointerException, "Item id is not set.");
411 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
412 event->getEventId()->setCalendarType(getType());
413 std::istringstream stream(event->getEventId()->getUId());
416 eventWrapper->getAbstractEvent()->setId(id);
418 std::stringstream ss(event->getEventId()->getRecurrenceId());
421 eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
423 LogDebug("id: " << id << ", rid: " << rid);
425 eventWrapper->convertAbstractEventToPlatformEvent();
427 eventWrapper->setCalendarId(getId());
428 eventWrapper->setCalendarAccountId(getAccountId());
429 eventWrapper->deleteEvent();
430 event->setResult(true);
432 Catch (NotFoundException)
434 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
435 event->setResult(false);
436 event->setExceptionCode(ExceptionCodes::NotFoundException);
440 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
441 event->setResult(false);
442 event->setExceptionCode(ExceptionCodes::UnknownException);
446 void Calendar::OnRequestReceived(const IEventGetPtr &event)
451 if (!event->getItemId()) {
452 ThrowMsg(NullPointerException, "Id parameter is NULL");
455 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
456 std::stringstream ss(event->getItemId()->getUId());
459 eventWrapper->loadEvent(id);
461 event->setItem(eventWrapper->getAbstractEvent());
462 event->setResult(true);
464 Catch (NotFoundException)
466 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
467 event->setResult(false);
468 event->setExceptionCode(ExceptionCodes::NotFoundException);
472 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
473 event->setResult(false);
474 event->setExceptionCode(ExceptionCodes::UnknownException);
478 void Calendar::OnRequestReceived(const IEventDeleteEventsPtr &events)
483 if (events->getEventIds()->empty()) {
484 ThrowMsg(NullPointerException, "Item id array is empty.");
487 int returnValue = calendar_svc_begin_trans();
488 if(CAL_SUCCESS!=returnValue) {
489 ThrowMsg(PlatformException, "Begin transaction failed with error code: "<<returnValue);
491 LogInfo("Begin transaction succeeded.");
494 bool failedDeleting = false;
495 for(unsigned int i=0; i<events->getEventIds()->size(); i++)
497 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
498 events->getEventIds()->at(i)->setCalendarType(getType());
499 std::istringstream stream(events->getEventIds()->at(i)->getUId());
502 eventWrapper->getAbstractEvent()->setId(id);
504 std::stringstream ss(events->getEventIds()->at(i)->getRecurrenceId());
507 eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
508 eventWrapper->convertAbstractEventToPlatformEvent();
511 eventWrapper->setCalendarId(getId());
512 eventWrapper->setCalendarAccountId(getAccountId());
513 eventWrapper->deleteEvent();
514 } Catch (NotFoundException) {
515 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
516 events->setExceptionCode(ExceptionCodes::NotFoundException);
517 failedDeleting = true;
518 } Catch (Exception) {
519 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
520 events->setExceptionCode(ExceptionCodes::PlatformException);
521 failedDeleting = true;
525 if( false==failedDeleting ) {
526 events->setResult(true);
527 returnValue = calendar_svc_end_trans(true);
528 LogInfo("End transaction return value with true flag: "<<returnValue);
530 events->setResult(false);
532 returnValue = calendar_svc_end_trans(false);
533 LogInfo("End transaction return value with false flag: "<<returnValue);
536 Catch (NotFoundException)
538 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
539 events->setResult(false);
540 events->setExceptionCode(ExceptionCodes::NotFoundException);
544 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
545 events->setResult(false);
546 events->setExceptionCode(ExceptionCodes::UnknownException);
550 void Calendar::OnRequestReceived(const IEventFindEventsPtr &event)
553 event->setResult(true);
559 CalendarFilterPtr calendarFilter( new CalendarFilter() );
561 std::string query (std::string("SELECT ") + CAL_VALUE_INT_INDEX + " FROM schedule_table");
562 LogInfo("Default query statement: "<<query);
564 TizenApis::Api::Tizen::IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<TizenApis::Api::Tizen::IFilterVisitor>(calendarFilter);
566 std::stringstream ssType;
567 std::stringstream ssAccount;
568 ssAccount<<getAccountId();
569 if (event->getGenericFilterIsSet()) {
570 TizenApis::Api::Tizen::FilterPtr genericFilter = event->getGenericFilter();
572 TizenApis::Api::Tizen::FilterValidatorPtr validator = CalendarFilterValidatorFactory::getCalendarFilterValidator();
573 bool success = genericFilter->validate(validator);
575 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
577 LogInfo("Filter validation has passed.");
580 genericFilter->travel(filterTraversal, 0);
581 LogDebug("Traverse string [" << calendarFilter->getResult() << "]");
582 query.append(calendarFilter->getResult());
583 query.append(std::string(" AND ") + CAL_VALUE_INT_ACCOUNT_ID + " = " + ssAccount.str());
584 if (getType()==CalendarEvent::TASK_TYPE) {
585 ssType<<CALS_CALENDAR_TYPE_TODO;
586 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str());
588 ssType<<CALS_CALENDAR_TYPE_EVENT;
589 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str());
592 query.append(std::string(" WHERE ") + CAL_VALUE_INT_ACCOUNT_ID + " = " + ssAccount.str());
593 if (getType()==CalendarEvent::TASK_TYPE) {
594 ssType<<CALS_CALENDAR_TYPE_TODO;
595 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str());
597 ssType<<CALS_CALENDAR_TYPE_EVENT;
598 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str());
602 if (event->getSortModesIsSet()) {
603 query.append(calendarFilter->makeQuerySortMode(event->getSortModes()));
604 query.append(std::string(";"));
607 LogDebug("Filter query [" << query << "]");
609 calendarFilter->executeQuery(query, event->getEvents());
611 LogDebug("Result count [" << event->getEvents()->size() << "]");
613 calendar_db_finish();
615 // Now load the full calendar item using the retrieved id.
616 for( unsigned int i=0; i<event->getEvents()->size(); i++) {
617 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvents()->at(i), getType()));
618 eventWrapper->loadEvent(event->getEvents()->at(i)->getId());
620 // If it's a detached event, set the saved rid.
621 if (eventWrapper->getAbstractEvent()->getParentId()>0) {
622 LogInfo("Set the saved rid: "<<calendar_svc_struct_get_lli(eventWrapper->getPlatformEvent(), CAL_VALUE_LLI_COMPLETED_TIME));
623 event->getEvents()->at(i)->setRecurrenceId(calendar_svc_struct_get_lli(eventWrapper->getPlatformEvent(), CAL_VALUE_LLI_COMPLETED_TIME));
627 Catch (InvalidArgumentException)
629 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
630 event->setResult(false);
631 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
633 Catch (NotFoundException)
635 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
636 event->setResult(false);
637 event->setExceptionCode(ExceptionCodes::NotFoundException);
641 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
642 event->setResult(false);
643 event->setExceptionCode(ExceptionCodes::UnknownException);
647 void Calendar::OnRequestReceived(const IEventCreateEventFromStringPtr &event)
652 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
653 eventWrapper->createEventFromString(event->getEventString());
654 event->setEvent(eventWrapper->convertPlatformEventToAbstractEvent());
655 event->getEvent()->setCalendarType(getType());
656 event->setResult(true);
658 Catch(PlatformException)
660 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
661 LogInfo("eventString: " + event->getEventString());
662 event->setResult(false);
663 event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
667 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
668 LogInfo("eventString: " + event->getEventString());
669 event->setResult(false);
670 event->setExceptionCode(ExceptionCodes::UnknownException);
674 void Calendar::OnRequestReceived(const IEventExportEventToStringPtr &event)
679 if (!event->getEvent()) {
680 ThrowMsg(NullPointerException, "event parameter is NULL");
683 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
684 event->getEvent()->setCalendarType(getType());
685 eventWrapper->convertAbstractEventToPlatformEvent();
686 event->setEventString(eventWrapper->exportEventToString());
687 event->setResult(true);
691 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
692 event->setResult(false);
693 event->setExceptionCode(ExceptionCodes::UnknownException);
697 static void eventChangedCb(void *user_data)
701 OnEventsChangedPtr eventPtr(new OnEventsChanged());
704 Calendar *thisCalendar = (Calendar*) user_data;
706 // Determine the status of event change.
707 cal_iter *iter = NULL;
708 cal_struct *platformEvent = NULL;
715 std::stringstream ss(thisCalendar->getId());
718 LogDebug("Getting items with calendar id: "<<calendarId<<", version: "<<thisCalendar->getLastChangedVersion()<<", type: "<<thisCalendar->getType());
719 if (CalendarEvent::TASK_TYPE==thisCalendar->getType()) {
720 errorCode = calendar_svc_todo_get_changes(calendarId,
721 thisCalendar->getLastChangedVersion(),
724 errorCode = calendar_svc_event_get_changes(calendarId,
725 thisCalendar->getLastChangedVersion(),
728 if( CAL_SUCCESS!=errorCode ) {
729 ThrowMsg(PlatformException, "Can't get the updated event list. Error code: "<<errorCode);
732 while( CAL_SUCCESS == calendar_svc_iter_next(iter) )
734 if ( CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent) ) {
735 ThrowMsg(PlatformException, "Can't get the calendar info.");
738 id = calendar_svc_struct_get_int(platformEvent, CALS_STRUCT_UPDATED_INT_ID);
739 type = calendar_svc_struct_get_int(platformEvent, CALS_STRUCT_UPDATED_INT_TYPE);
740 version = calendar_svc_struct_get_int(platformEvent, CALS_STRUCT_UPDATED_INT_VERSION);
741 LogDebug("id "<<id<<", type "<<type<<", version "<<version);
742 if ( CALS_UPDATED_TYPE_INSERTED==type ) {
743 eventPtr->setStatus(OnEventsChanged::ON_ADD);
744 } else if ( CALS_UPDATED_TYPE_MODIFIED==type ) {
745 eventPtr->setStatus(OnEventsChanged::ON_UPDATE);
746 } else if ( CALS_UPDATED_TYPE_DELETED==type ) {
747 eventPtr->setStatus(OnEventsChanged::ON_DELETE);
749 if( platformEvent ) {
750 calendar_svc_struct_free(&platformEvent);
752 calendar_svc_iter_remove(&iter);
753 ThrowMsg(PlatformException, "Wrong syncStatus.");
756 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisCalendar->getType()));
758 eventWrapper->loadEvent(id);
759 } Catch (NotFoundException){
760 LogDebug("Handling deleted event with index: "<<id);
762 eventPtr->addEvent(eventWrapper->getAbstractEvent());
764 if ( CAL_SUCCESS != calendar_svc_struct_free(&platformEvent) ) {
765 ThrowMsg(PlatformException, "Can't free the platform event struct.");
769 if ( CAL_SUCCESS != calendar_svc_iter_remove(&iter) ) {
770 ThrowMsg(PlatformException, "Can't remove the iter.");
773 thisCalendar->setLastChangedVersion(version);
774 LogInfo("Last change fetch version: "<<thisCalendar->getLastChangedVersion());
776 eventPtr->setResult(true);
777 eventPtr->setCalendarType(thisCalendar->getType());
779 if( eventPtr->getEventList()->size() > 0 ) {
780 thisCalendar->m_changeEmitters.emit(eventPtr);
782 LogInfo("No actual changes. Skip signal emission.");
787 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
791 void Calendar::OnRequestReceived(const IEventWatchChangesPtr &event)
796 // Subscribe the watch to the platform just once.
797 if( m_changeEmitters.size()==0 )
799 if (CAL_SUCCESS!=calendar_svc_begin_trans() ) {
800 ThrowMsg(PlatformException, "Transaction failed.");
802 if( CAL_SUCCESS!=calendar_svc_subscribe_change(eventChangedCb, this) ) {
803 calendar_svc_end_trans(true);
804 ThrowMsg(PlatformException, "Can't subscribe the db change noti.");
806 // Save the last change fetch version to start watching.
807 int version = calendar_svc_end_trans(true);
808 setLastChangedVersion(version);
809 LogInfo("Last change fetch version: "<<getLastChangedVersion());
814 m_changeEmitters.attach(event->getEmitter());
815 event->setWatchId(event->getEmitter()->getId());
816 event->setResult(true);
820 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
821 event->setResult(false);
822 event->setExceptionCode(ExceptionCodes::UnknownException);
826 void Calendar::OnRequestReceived(const IEventClearWatchPtr &event)
831 if( m_changeEmitters.detach(event->getWatchId()) ) {
832 if( m_changeEmitters.size()==0 ) {
833 if( CAL_SUCCESS!=calendar_svc_unsubscribe_change(eventChangedCb) ) {
834 ThrowMsg(PlatformException, "Can't unsubscribe the db change noti.");
836 LogDebug("Platform watch cleared successfully.");
839 event->setResult(true);
841 LogInfo("Wrong watch Id.");
842 event->setResult(false);
847 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
848 event->setResult(false);
849 event->setExceptionCode(ExceptionCodes::UnknownException);
853 void Calendar::OnRequestReceived(const IEventExpandEventRecurrencePtr &event)
856 const CalendarEventPtr calEvent = event->getEvent();
857 const long long int startDate = event->getStartDate();
858 const long long int endDate = event->getEndDate();
859 event->setResult(true);
862 if ( 0 >= calEvent->getRecurrenceRule()->getFrequency())
864 ThrowMsg(PlatformException, "This is not a recurring event.");
867 DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(CalendarEvent::EVENT_TYPE));
868 // We must load the event from the DB in order to get the auto-calculated repeat end time.
869 eventWrapper->loadEvent(calEvent->getId());
871 cal_iter *iter = NULL;
874 long long int dtstart, dtend;
876 std::stringstream ss(getId());
879 int returnVal = calendar_svc_event_get_normal_list_by_period(calendarId, CALS_LIST_PERIOD_NORMAL_BASIC, startDate, endDate, &iter);
880 if( CAL_SUCCESS!=returnVal ) {
881 ThrowMsg(PlatformException, "Getting event instances failed due to "<<returnVal);
884 while ( CAL_SUCCESS==calendar_svc_iter_next(iter) )
887 returnVal = calendar_svc_iter_get_info(iter, &cs);
888 if( CAL_SUCCESS!=returnVal ){
889 LogDebug("Iterator get info failed due to "<<returnVal);
893 candidateIndex = calendar_svc_struct_get_int(cs, CALS_LIST_PERIOD_NORMAL_BASIC_INT_EVENTID);
894 if(candidateIndex==calEvent->getId()) {
895 DPL::ScopedPtr<EventWrapper> recurringEventWrapper(new EventWrapper(getType()));
896 recurringEventWrapper->loadEvent(calEvent->getId());
898 // Set distintive attributes of each instance.
899 dtstart = calendar_svc_struct_get_lli(cs, CALS_LIST_PERIOD_NORMAL_BASIC_LLI_DTSTART_UTIME);
900 dtend = calendar_svc_struct_get_lli(cs, CALS_LIST_PERIOD_NORMAL_BASIC_LLI_DTEND_UTIME);
901 recurringEventWrapper->getAbstractEvent()->setRecurrenceId(dtstart);
902 recurringEventWrapper->getAbstractEvent()->setStartTime(dtstart);
903 recurringEventWrapper->getAbstractEvent()->setEndTime(dtend);
904 LogInfo("Found a valid event instance with dtstart: "<<dtstart<<" and dtend: "<<dtend);
906 event->addExpandedEvent(recurringEventWrapper->getAbstractEvent());
909 LogInfo("Length of expanded events from parent: "<<event->getExpandedEventList()->size());
911 // Consider the detached events also.
913 cal_struct *platformEvent = NULL;
914 int parentId = event->getEvent()->getId();
915 if(CAL_SUCCESS != calendar_svc_find_event_list(getAccountId(), CAL_VALUE_INT_ORIGINAL_EVENT_ID, (void*) parentId, &iter)) {
916 LogInfo("No detached instances found.");
919 while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
920 platformEvent = NULL;
921 if (CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent)) {
922 ThrowMsg(PlatformException, "Can't get event info.");
925 int detachedEventId = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
926 long long int detachedStartTime = calendar_svc_struct_get_lli(platformEvent, CALS_VALUE_LLI_DTSTART_UTIME);
927 long long int detachedEndTime = calendar_svc_struct_get_lli(platformEvent, CALS_VALUE_LLI_DTEND_UTIME);
928 if (detachedStartTime>=startDate && detachedStartTime<=endDate) {
929 LogInfo("Found a valid detached event: "<<detachedStartTime);
930 DPL::ScopedPtr<EventWrapper> detachedEventWrapper(new EventWrapper(getType()));
931 detachedEventWrapper->loadEvent(detachedEventId);
933 // Set the same parent uid to each instances
934 detachedEventWrapper->getAbstractEvent()->setId(parentId);
935 // Set distintive attributes of each instance.
936 detachedEventWrapper->getAbstractEvent()->setRecurrenceId(detachedStartTime);
937 detachedEventWrapper->getAbstractEvent()->setStartTime(detachedStartTime);
938 detachedEventWrapper->getAbstractEvent()->setEndTime(detachedEndTime);
940 event->addExpandedEvent(detachedEventWrapper->getAbstractEvent());
944 LogInfo("Length of total expanded events: "<<event->getExpandedEventList()->size());
948 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
949 event->setResult(false);
950 event->setExceptionCode(ExceptionCodes::UnknownException);