upload tizen1.0 source
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Calendar / Calendar.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 #include <calendar-svc-provider.h>
19 #include <dpl/log/log.h>
20 #include <dpl/scoped_ptr.h>
21 #include "Calendar.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>
32 #include <sstream>
33
34 using namespace TizenApis::Api::Calendar;
35 using namespace WrtDeviceApis::Commons;
36
37 namespace TizenApis {
38 namespace Platform {
39 namespace Calendar {
40
41 Calendar::Calendar()
42 {
43     LogDebug("entered");
44 }
45
46 Calendar::~Calendar()
47 {
48     LogDebug("entered");
49 }
50
51 void Calendar::OnRequestReceived(const IEventAddEventPtr &event)
52 {
53     LogDebug("entered");
54     Try
55     {
56         if (!event->getEvent()) {
57             ThrowMsg(NullPointerException, "event parameter is NULL");
58         }
59         if (event->getEvent()->getIdIsSet()) {
60             LogWarning("adding event that is already added");
61             event->getEvent()->resetId();
62         }
63         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
64         event->getEvent()->setCalendarType(getType());
65         eventWrapper->convertAbstractEventToPlatformEvent();
66
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);
72     }
73     Catch (Exception)
74     {
75         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
76         event->setResult(false);
77         event->setExceptionCode(ExceptionCodes::UnknownException);
78     }
79 }
80
81 void Calendar::OnRequestReceived(const IEventAddEventsPtr &events)
82 {
83     LogDebug("entered");
84
85     Try
86     {
87         if (events->getEvents()->empty()) {
88             ThrowMsg(NullPointerException, "event vector parameter is empty");
89         }
90
91         // Save the vector of events iteratively
92         bool failedAdding = false;
93         for(unsigned int i=0; i<events->getEvents()->size(); i++)
94         {
95             if (events->checkCancelled()) {
96                 events->setCancelAllowed(true);
97                 events->setResult(true);
98                 return;
99             }
100
101             if (events->getEvents()->at(i)->getIdIsSet()) {
102                 LogWarning("adding event that is already added: index " << i);
103                 events->getEvents()->at(i)->resetId();
104             }
105             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(events->getEvents()->at(i), getType()));
106             events->getEvents()->at(i)->setCalendarType(getType());
107             eventWrapper->convertAbstractEventToPlatformEvent();
108
109             Try {
110                 // Set the account and calendar id before saving the item.
111                 eventWrapper->setCalendarId(getId());
112                 eventWrapper->setCalendarAccountId(getAccountId());
113                 eventWrapper->saveEvent();
114             } Catch (Exception) {
115                 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
116                 failedAdding = true;
117             }
118             //getAddEmitter()->emit(eventPtr);
119         }
120
121         if( false==failedAdding ) {
122             events->setResult(true);
123         } else {
124             events->setResult(false);
125         }
126     }
127     Catch (Exception)
128     {
129         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
130         events->setResult(false);
131         events->setExceptionCode(ExceptionCodes::UnknownException);
132     }
133     events->setCancelAllowed(false);
134 }
135
136 void Calendar::OnRequestReceived(const IEventUpdateEventPtr &event)
137 {
138     LogDebug("entered");
139
140     cal_iter *iter = NULL;
141     Try
142     {
143         if (!event->getEvent()) {
144             ThrowMsg(NullPointerException, "Item object is NULL.");
145         }
146         if (!event->getEvent()->getIdIsSet()) {
147             ThrowMsg(InvalidArgumentException, "Item id is not set.");
148         }
149
150         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
151         event->getEvent()->setCalendarType(getType());
152         eventWrapper->convertAbstractEventToPlatformEvent();
153
154         if ( event->getUpdateAllInstances() || 0>=event->getEvent()->getRecurrenceRule()->getFrequency())
155         {
156             // Update all parent and child instances with the given uid.
157             int parentId = event->getEvent()->getId();
158
159             // First, the parent event.
160             eventWrapper->saveEvent();
161
162             // Next, all the detached instances.
163             cal_struct *platformEvent = NULL;
164             if(CAL_SUCCESS != calendar_svc_find_event_list(getAccountId(), CAL_VALUE_INT_ORIGINAL_EVENT_ID, (void*) parentId, &iter)) {
165                 LogInfo("No detached instances found.");
166             }
167
168             while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
169                 platformEvent = NULL;
170                 if (CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent)) {
171                     ThrowMsg(PlatformException, "Can't get event info.");
172                 }
173
174                 int detachedEventId = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
175                 std::time_t detachedStartTime = calendar_svc_struct_get_time(platformEvent,
176                                                                             CAL_VALUE_GMT_START_DATE_TIME,
177                                                                             CAL_TZ_FLAG_GMT);
178                 std::time_t detachedEndTime = calendar_svc_struct_get_time(platformEvent,
179                                                                             CAL_VALUE_GMT_END_DATE_TIME,
180                                                                             CAL_TZ_FLAG_GMT);
181
182                 DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(event->getEvent(), getType()));
183                 eventWrapperChild->convertAbstractEventToPlatformEvent();
184                 if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
185                                                                CAL_VALUE_INT_INDEX,
186                                                                detachedEventId)) {
187                     ThrowMsg(PlatformException, "Can't set event Id.");
188                 }
189                 if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
190                                                                CAL_VALUE_INT_ORIGINAL_EVENT_ID,
191                                                                parentId)) {
192                     ThrowMsg(PlatformException, "Can't set parent Id.");
193                 }
194                 if (CAL_SUCCESS != calendar_svc_struct_set_time(eventWrapperChild->getPlatformEvent(),
195                                                                CAL_VALUE_GMT_START_DATE_TIME,
196                                                                CAL_TZ_FLAG_GMT,
197                                                                detachedStartTime)) {
198                     ThrowMsg(PlatformException, "Can't set start time.");
199                 }
200                 if (CAL_SUCCESS != calendar_svc_struct_set_time(eventWrapperChild->getPlatformEvent(),
201                                                                CAL_VALUE_GMT_END_DATE_TIME,
202                                                                CAL_TZ_FLAG_GMT,
203                                                                detachedEndTime)) {
204                     ThrowMsg(PlatformException, "Can't set end time.");
205                 }
206                 if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
207                                                                CAL_VALUE_INT_REPEAT_TERM,
208                                                                CAL_REPEAT_NONE)) {
209                     ThrowMsg(PlatformException, "Can't set repeat term.");
210                 }
211
212                 eventWrapperChild->saveEvent();
213                 LogDebug("Updated a detached event by id: "<<detachedEventId);
214             }
215         }
216         else
217         {
218             LogDebug("Update the exception record");
219             DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(event->getEvent(), getType()));
220             eventWrapperChild->convertAbstractEventToPlatformEvent();
221             if ( CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
222                 CAL_VALUE_INT_ORIGINAL_EVENT_ID, event->getEvent()->getId()) ) {
223                 ThrowMsg(PlatformException, "cannot save exception event");
224             } 
225             // Use "CAL_VALUE_GMT_COMPLETED_DATE_TIME" as the recurrence id saving point.
226             if ( CAL_SUCCESS!=calendar_svc_struct_set_time(eventWrapperChild->getPlatformEvent(),
227                 CAL_VALUE_GMT_COMPLETED_DATE_TIME, CAL_TZ_FLAG_GMT, event->getEvent()->getRecurrenceId()) ) {
228                 ThrowMsg(PlatformException, "cannot save recurrence id");
229             } else {
230                 LogInfo("Saved the rid for the child: "<<event->getEvent()->getRecurrenceId());
231             }
232             if (CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
233                 CAL_VALUE_INT_REPEAT_TERM, CAL_REPEAT_NONE) ) {
234                 ThrowMsg(PlatformException, "cannot save exception event");
235             }
236             int childId = calendar_svc_insert(eventWrapperChild->getPlatformEvent());
237             if ( childId<0 ) {
238                 ThrowMsg(PlatformException, "cannot save exception event");
239             }
240
241             GList* list = NULL;
242             cal_value *value = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE);
243             if (CAL_SUCCESS!=calendar_svc_value_set_time(value, CAL_VALUE_GMT_EXCEPTION_DATE_TIME, CAL_TZ_FLAG_GMT, event->getEvent()->getRecurrenceId()) ) {
244                 ThrowMsg(PlatformException, "cannot save the exception date");
245             } else {
246                 LogInfo("Saved the exception date: "<<event->getEvent()->getRecurrenceId());
247             }
248             if (CAL_SUCCESS!=calendar_svc_value_set_int(value,  CAL_VALUE_INT_EXCEPTION_DATE_ID, childId)) {
249                 ThrowMsg(PlatformException, "cannot save the exception parent event");
250             } else {
251                 LogInfo("Saved the exception id: "<<childId);
252             }
253             eventWrapper->loadEvent(event->getEvent()->getId());
254             calendar_svc_struct_get_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, &list);
255             list = g_list_append(list, value);
256             if (CAL_SUCCESS!=calendar_svc_struct_store_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, list)) {
257                 ThrowMsg(PlatformException, "cannot save the exception parent event");
258             }
259             calendar_svc_update(eventWrapper->getPlatformEvent());
260
261             event->getEvent()->setIsDetached(true);
262         }
263
264         event->setResult(true);
265     }
266     Catch (Exception)
267     {
268         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
269         event->setResult(false);
270         event->setExceptionCode(ExceptionCodes::UnknownException);
271     }
272
273     if(iter) {
274         calendar_svc_iter_remove(&iter);
275     }
276 }
277
278 void Calendar::OnRequestReceived(const IEventUpdateEventsPtr &events)
279 {
280     LogDebug("entered");
281
282     cal_iter *iter = NULL;
283     Try
284     {
285         if (events->getEvents()->empty()) {
286             ThrowMsg(NullPointerException, "Item vector is empty.");
287         }
288
289         // Update the vector of events iteratively
290         bool failedUpdating = false;
291         for(unsigned int i=0; i<events->getEvents()->size(); i++)
292         {
293             if (events->checkCancelled()) {
294                 events->setCancelAllowed(true);
295                 events->setResult(true);
296                 return;
297             }
298
299             CalendarEventPtr thisEvent = events->getEvents()->at(i);
300             if (!thisEvent->getIdIsSet()) {
301                 ThrowMsg(InvalidArgumentException, "Item id is not set.");
302             }
303             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisEvent, getType()));
304             events->getEvents()->at(i)->setCalendarType(getType());
305             eventWrapper->convertAbstractEventToPlatformEvent();
306
307             try {
308                 if (events->getUpdateAllInstances() || 0>=thisEvent->getRecurrenceRule()->getFrequency())
309                 {
310                     // Update all parent and child instances with the given uid.
311                     int parentId = thisEvent->getId();
312
313                     // First, the parent event.
314                     eventWrapper->saveEvent();
315                     
316                     // Next, all the detached instances.
317                     cal_struct *platformEvent = NULL;
318                     if(CAL_SUCCESS != calendar_svc_find_event_list(getAccountId(), CAL_VALUE_INT_ORIGINAL_EVENT_ID, (void*) parentId, &iter)) {
319                         LogInfo("No detached instances found.");
320                     }
321
322                     while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
323                         platformEvent = NULL;
324                         if (CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent)) {
325                             ThrowMsg(PlatformException, "Can't get event info.");
326                         }
327
328                         int detachedEventId = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
329                         std::time_t detachedStartTime = calendar_svc_struct_get_time(platformEvent,
330                                                                                     CAL_VALUE_GMT_START_DATE_TIME,
331                                                                                     CAL_TZ_FLAG_GMT);
332                         std::time_t detachedEndTime = calendar_svc_struct_get_time(platformEvent,
333                                                                                     CAL_VALUE_GMT_END_DATE_TIME,
334                                                                                     CAL_TZ_FLAG_GMT);
335
336                         DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(thisEvent, getType()));
337                         eventWrapperChild->convertAbstractEventToPlatformEvent();
338                         if (CAL_SUCCESS != calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
339                                                                        CAL_VALUE_INT_INDEX,
340                                                                        detachedEventId)) {
341                             ThrowMsg(PlatformException, "Can't set event Id.");
342                         }
343                         if (CAL_SUCCESS != calendar_svc_struct_set_time(eventWrapperChild->getPlatformEvent(),
344                                                                        CAL_VALUE_GMT_START_DATE_TIME,
345                                                                        CAL_TZ_FLAG_GMT,
346                                                                        detachedStartTime)) {
347                             ThrowMsg(PlatformException, "Can't set start time.");
348                         }
349                         if (CAL_SUCCESS != calendar_svc_struct_set_time(eventWrapperChild->getPlatformEvent(),
350                                                                        CAL_VALUE_GMT_END_DATE_TIME,
351                                                                        CAL_TZ_FLAG_GMT,
352                                                                        detachedEndTime)) {
353                             ThrowMsg(PlatformException, "Can't set end time.");
354                         }
355
356                         eventWrapper->saveEvent();
357                         LogDebug("Updated a detached event by id: "<<detachedEventId);
358                     }
359                 }
360                 else
361                 {
362                     LogDebug("Update the exception record");
363                     DPL::ScopedPtr<EventWrapper> eventWrapperChild(new EventWrapper(thisEvent, getType()));
364                     eventWrapperChild->convertAbstractEventToPlatformEvent();
365
366                     if ( CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
367                         CAL_VALUE_INT_ORIGINAL_EVENT_ID, thisEvent->getId()) ) {
368                         ThrowMsg(PlatformException, "cannot save parent id.");
369                     }
370                     // Use "CAL_VALUE_GMT_COMPLETED_DATE_TIME" as the recurrence id saving point.
371                     if ( CAL_SUCCESS!=calendar_svc_struct_set_time(eventWrapperChild->getPlatformEvent(),
372                         CAL_VALUE_GMT_COMPLETED_DATE_TIME, CAL_TZ_FLAG_GMT, thisEvent->getRecurrenceId()) ) {
373                         ThrowMsg(PlatformException, "cannot save recurrence id.");
374                     } else {
375                         LogInfo("Saved the rid for the child: "<<thisEvent->getRecurrenceId());
376                     }
377                     if (CAL_SUCCESS!=calendar_svc_struct_set_int(eventWrapperChild->getPlatformEvent(),
378                         CAL_VALUE_INT_REPEAT_TERM, CAL_REPEAT_NONE) ) {
379                         ThrowMsg(PlatformException, "cannot save repeat term.");
380                     }
381                     int childId = calendar_svc_insert(eventWrapperChild->getPlatformEvent());
382                     if ( childId<0 ) {
383                         ThrowMsg(PlatformException, "cannot save exception event");
384                     }
385
386                     GList* list = NULL;
387                     cal_value *value = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE);
388                     if (CAL_SUCCESS!=calendar_svc_value_set_time(value, CAL_VALUE_GMT_EXCEPTION_DATE_TIME, CAL_TZ_FLAG_GMT, thisEvent->getRecurrenceId()) ) {
389                         ThrowMsg(PlatformException, "cannot save the exception parent event");
390                     } else {
391                         LogInfo("Saved the exception date: "<<thisEvent->getRecurrenceId());
392                     }
393                     if (CAL_SUCCESS!=calendar_svc_value_set_int(value,  CAL_VALUE_INT_EXCEPTION_DATE_ID, childId)) {
394                         ThrowMsg(PlatformException, "cannot save the exception parent event");
395                     } else {
396                         LogInfo("Saved the exception id: "<<childId);
397                     }
398                     calendar_svc_struct_get_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, &list);
399                     list = g_list_append(list, value);
400                     if (CAL_SUCCESS!=calendar_svc_struct_store_list(eventWrapper->getPlatformEvent(), CAL_VALUE_LST_EXCEPTION_DATE, list)) {
401                         ThrowMsg(PlatformException, "cannot save the exception parent event");
402                     }
403                     calendar_svc_update(eventWrapper->getPlatformEvent());
404
405                     thisEvent->setIsDetached(true);
406                 }
407             } Catch (Exception) {
408                 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
409                 failedUpdating = true;
410             }
411             //getUpdateEmitter()->emit(eventPtr);
412         }
413
414         if( false==failedUpdating ) {
415             events->setResult(true);
416         } else {
417             events->setResult(false);
418         }
419     }
420     Catch (Exception)
421     {
422         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
423         events->setResult(false);
424         events->setExceptionCode(ExceptionCodes::UnknownException);
425     }
426
427     if(iter) {
428         calendar_svc_iter_remove(&iter);
429     }
430     events->setCancelAllowed(false);
431 }
432
433 void Calendar::OnRequestReceived(const IEventDeleteEventPtr &event)
434 {
435     LogDebug("entered");
436     Try
437     {
438         if (!event->getEventId()) {
439             ThrowMsg(NullPointerException, "Item id is not set.");
440         }
441
442         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
443         event->getEventId()->setCalendarType(getType());
444         std::istringstream stream(event->getEventId()->getUId());
445         int id = -1;
446         stream>>id;
447         eventWrapper->getAbstractEvent()->setId(id);
448
449         std::stringstream ss(event->getEventId()->getRecurrenceId());
450         std::time_t rid;
451         ss>>rid;
452         eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
453
454         LogDebug("id: " << id << ", rid: " << rid);
455
456         eventWrapper->convertAbstractEventToPlatformEvent();
457
458         eventWrapper->setCalendarId(getId());
459         eventWrapper->setCalendarAccountId(getAccountId());
460         eventWrapper->deleteEvent();
461         event->setResult(true);
462     }
463     Catch (NotFoundException)
464     {
465         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
466         event->setResult(false);
467         event->setExceptionCode(ExceptionCodes::NotFoundException);
468     }
469     Catch (Exception)
470     {
471         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
472         event->setResult(false);
473         event->setExceptionCode(ExceptionCodes::UnknownException);
474     }
475 }
476
477 void Calendar::OnRequestReceived(const IEventGetPtr &event)
478 {
479     LogDebug("entered");
480     Try
481     {
482         if (!event->getItemId()) {
483             ThrowMsg(NullPointerException, "Id parameter is NULL");
484         }
485
486         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
487         std::stringstream ss(event->getItemId()->getUId());
488         int id = -1;
489         ss>>id;
490         eventWrapper->loadEvent(id);
491
492         event->setItem(eventWrapper->convertPlatformEventToAbstractEvent());
493         event->setResult(true);
494     }
495     Catch (NotFoundException)
496     {
497         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
498         event->setResult(false);
499         event->setExceptionCode(ExceptionCodes::NotFoundException);
500     }
501     Catch (Exception)
502     {
503         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
504         event->setResult(false);
505         event->setExceptionCode(ExceptionCodes::UnknownException);
506     }
507 }
508
509 void Calendar::OnRequestReceived(const IEventDeleteEventsPtr &events)
510 {
511     LogDebug("entered");
512     Try
513     {
514         if (events->getEventIds()->empty()) {
515             ThrowMsg(NullPointerException, "event vector parameter is empty");
516         }
517
518         // Delete the vector of events iteratively considering the recurrenceId
519         bool failedDeleting = false;
520         for(unsigned int i=0; i<events->getEventIds()->size(); i++)
521         {
522             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
523             events->getEventIds()->at(i)->setCalendarType(getType());
524             std::istringstream stream(events->getEventIds()->at(i)->getUId());
525             int id = -1;
526             stream>>id;
527             eventWrapper->getAbstractEvent()->setId(id);
528
529             std::stringstream ss(events->getEventIds()->at(i)->getRecurrenceId());
530             std::time_t rid;
531             ss>>rid;
532             eventWrapper->getAbstractEvent()->setRecurrenceId(rid);
533             eventWrapper->convertAbstractEventToPlatformEvent();
534
535             Try {
536                 eventWrapper->setCalendarId(getId());
537                 eventWrapper->setCalendarAccountId(getAccountId());
538                 eventWrapper->deleteEvent();
539             } Catch (NotFoundException) {
540                 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
541                 events->setExceptionCode(ExceptionCodes::NotFoundException);
542                 failedDeleting = true;
543             } Catch (Exception) {
544                 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
545                 events->setExceptionCode(ExceptionCodes::PlatformException);
546                 failedDeleting = true;
547             }
548         }
549
550         if( false==failedDeleting ) {
551             events->setResult(true);
552         }
553         else {
554             events->setResult(false);
555         }
556     }
557     Catch (NotFoundException)
558     {
559         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
560         events->setResult(false);
561         events->setExceptionCode(ExceptionCodes::NotFoundException);
562     }
563     Catch (Exception)
564     {
565         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
566         events->setResult(false);
567         events->setExceptionCode(ExceptionCodes::UnknownException);
568     }
569 }
570
571 void Calendar::OnRequestReceived(const IEventFindEventsPtr &event)
572 {
573     LogDebug("entered");
574     event->setResult(true);
575
576     Try
577     {
578         calendar_db_init();
579
580         CalendarFilterPtr calendarFilter( new CalendarFilter() );
581
582         std::string query (std::string("SELECT ") + CAL_VALUE_INT_INDEX + " FROM schedule_table");
583         LogInfo("Default query statement: "<<query);
584
585                 TizenApis::Api::Tizen::IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<TizenApis::Api::Tizen::IFilterVisitor>(calendarFilter);
586
587         std::stringstream ssType;
588         std::stringstream ssAccount;
589         ssAccount<<getAccountId();
590                 if (event->getGenericFilterIsSet()) {
591             TizenApis::Api::Tizen::FilterPtr genericFilter = event->getGenericFilter();
592
593             TizenApis::Api::Tizen::FilterValidatorPtr validator = CalendarFilterValidatorFactory::getCalendarFilterValidator();
594             bool success = genericFilter->validate(validator);
595             if(!success) {
596                 ThrowMsg(InvalidArgumentException, "Invalid filter arguments.");
597             } else {
598                 LogInfo("Filter validation has passed.");
599             }
600
601                         genericFilter->travel(filterTraversal, 0);
602                         LogDebug("Traverse string [" << calendarFilter->getResult() << "]");
603                         query.append(calendarFilter->getResult());
604             query.append(std::string(" AND ") + CAL_VALUE_INT_ACCOUNT_ID + " = " + ssAccount.str());
605             if (getType()==CalendarEvent::TASK_TYPE) {
606                 ssType<<CALS_CALENDAR_TYPE_TODO;
607                 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0");
608             } else {
609                 ssType<<CALS_CALENDAR_TYPE_EVENT;
610                 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0");
611             }
612                 } else {
613             query.append(std::string(" WHERE ") + CAL_VALUE_INT_ACCOUNT_ID + " = " + ssAccount.str());
614             if (getType()==CalendarEvent::TASK_TYPE) {
615                 ssType<<CALS_CALENDAR_TYPE_TODO;
616                 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0");
617             } else {
618                 ssType<<CALS_CALENDAR_TYPE_EVENT;
619                 query.append(std::string(" AND ") + CAL_VALUE_INT_TYPE + " = " + ssType.str() + " AND " + "is_deleted = 0");
620             }
621                 }
622
623                 if (event->getSortModesIsSet()) {
624                         query.append(calendarFilter->makeQuerySortMode(event->getSortModes()));
625                         query.append(std::string(";"));
626                 }
627
628                 LogDebug("Filter query [" << query << "]");
629
630                 calendarFilter->executeQuery(query, event->getEvents());
631
632         LogDebug("Result count [" << event->getEvents()->size() << "]");
633
634         calendar_db_finish();
635
636         // Now load the full calendar item using the retrieved id.
637         for( unsigned int i=0; i<event->getEvents()->size(); i++) {
638             // platformEvent is freed when the wrapper destructor is called.
639             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvents()->at(i), getType()));
640             eventWrapper->loadEvent(event->getEvents()->at(i)->getId());
641
642             // If it's a detached event, set the saved rid.
643             if (eventWrapper->getAbstractEvent()->getParentId()>0) {
644                 LogInfo("Set the saved rid: "<<calendar_svc_struct_get_time(eventWrapper->getPlatformEvent(), CAL_VALUE_GMT_COMPLETED_DATE_TIME, CAL_TZ_FLAG_GMT));
645                 event->getEvents()->at(i)->setRecurrenceId(calendar_svc_struct_get_time(eventWrapper->getPlatformEvent(), CAL_VALUE_GMT_COMPLETED_DATE_TIME, CAL_TZ_FLAG_GMT));
646             }
647         }
648     }
649     Catch (InvalidArgumentException)
650     {
651         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
652         event->setResult(false);
653         event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
654     }
655     Catch (NotFoundException)
656     {
657         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
658         event->setResult(false);
659         event->setExceptionCode(ExceptionCodes::NotFoundException);
660     }
661     Catch (Exception)
662     {
663         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
664         event->setResult(false);
665         event->setExceptionCode(ExceptionCodes::UnknownException);
666     }
667 }
668
669 void Calendar::OnRequestReceived(const IEventCreateEventFromStringPtr &event)
670 {
671     LogDebug("entered");
672     Try
673     {
674         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(getType()));
675         eventWrapper->createEventFromString(event->getEventString());
676         event->setEvent(eventWrapper->convertPlatformEventToAbstractEvent());
677         event->getEvent()->setCalendarType(getType());
678         event->setResult(true);
679     }
680     Catch(PlatformException)
681     {
682                 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
683         LogInfo("eventString: " + event->getEventString());
684         event->setResult(false);
685         event->setExceptionCode(ExceptionCodes::InvalidArgumentException);
686     }
687     Catch (Exception)
688     {
689         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
690         LogInfo("eventString: " + event->getEventString());
691         event->setResult(false);
692         event->setExceptionCode(ExceptionCodes::UnknownException);
693     }
694 }
695
696 void Calendar::OnRequestReceived(const IEventExportEventToStringPtr &event)
697 {
698     LogDebug("entered");
699     Try
700     {
701         if (!event->getEvent()) {
702             ThrowMsg(NullPointerException, "event parameter is NULL");
703         }
704
705         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(event->getEvent(), getType()));
706         event->getEvent()->setCalendarType(getType());
707         eventWrapper->convertAbstractEventToPlatformEvent();
708         event->setEventString(eventWrapper->exportEventToString());
709         event->setResult(true);
710     }
711     Catch (Exception)
712     {
713         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
714         event->setResult(false);
715         event->setExceptionCode(ExceptionCodes::UnknownException);
716     }
717 }
718
719 static void eventChangedCb(void *user_data)
720 {
721     LogDebug("entered");
722
723     OnEventsChangedPtr eventPtr(new OnEventsChanged());
724     Try
725     {
726         Calendar *thisCalendar = (Calendar*) user_data;
727
728         // Determine the status of event change.
729         cal_iter *iter = NULL;
730         cal_struct *platformEvent = NULL;
731         int index;
732         int syncStatus;
733
734         if( CAL_SUCCESS != calendar_svc_get_updated_event_list(thisCalendar->getAccountId(),
735                 thisCalendar->getLastChangeFetchTime(),
736                 &iter) ) {
737             ThrowMsg(PlatformException, "Can't get the updated event list.");
738         }
739         while( CAL_SUCCESS == calendar_svc_iter_next(iter) )
740         {
741             if ( CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent) ) {
742                 ThrowMsg(PlatformException, "Can't get the calendar info.");
743             }
744
745             index = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
746             syncStatus = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_SYNC_STATUS);
747             LogDebug("index "<<index<<" , syncStatus "<<syncStatus);
748             if ( CAL_SYNC_STATUS_NEW==syncStatus ) {
749                 eventPtr->setStatus(OnEventsChanged::ON_ADD);
750             } else if ( CAL_SYNC_STATUS_UPDATED==syncStatus ) {
751                 eventPtr->setStatus(OnEventsChanged::ON_UPDATE);
752             } else if ( CAL_SYNC_STATUS_DELETED==syncStatus ) {
753                 eventPtr->setStatus(OnEventsChanged::ON_DELETE);
754             } else {
755                 if( platformEvent ) {
756                     calendar_svc_struct_free(&platformEvent);
757                 }
758                 calendar_svc_iter_remove(&iter);
759                 ThrowMsg(PlatformException, "Wrong syncStatus.");
760             }
761
762             DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(thisCalendar->getType()));
763             Try {
764                 eventWrapper->loadEvent(index);
765             } Catch (NotFoundException){
766                 LogDebug("Handling deleted event with index: "<<index);
767             }
768             eventPtr->addEvent(eventWrapper->getAbstractEvent());
769
770             if ( CAL_SUCCESS != calendar_svc_struct_free(&platformEvent) ) {
771                 ThrowMsg(PlatformException, "Can't free the platform event struct.");
772             }
773         }
774
775         if ( CAL_SUCCESS != calendar_svc_iter_remove(&iter) ) {
776             ThrowMsg(PlatformException, "Can't remove the iter.");
777         }
778
779         std::time_t localTime = time(NULL);
780         thisCalendar->setLastChangeFetchTime(localTime);
781         LogInfo("Last change fetch time: "<<thisCalendar->getLastChangeFetchTime());
782
783         eventPtr->setResult(true);
784         eventPtr->setCalendarType(thisCalendar->getType());
785
786         if( eventPtr->getEventList()->size() > 0 ) {
787             thisCalendar->m_changeEmitters.emit(eventPtr);
788         } else {
789             LogInfo("No actual changes. Skip signal emission.");
790         }
791     }
792     Catch (Exception)
793     {
794         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
795     }
796 }
797
798 void Calendar::OnRequestReceived(const IEventWatchChangesPtr &event)
799 {
800     LogDebug("entered");
801     Try
802     {
803         // Subscribe the watch to the platform just once.
804         if( m_changeEmitters.size()==0 )
805         {
806             if( CAL_SUCCESS!=calendar_svc_subscribe_change(eventChangedCb, this) ) {
807                 ThrowMsg(PlatformException, "Can't subscribe the db change noti.");
808             } else {
809                 // Save the last change fetch time to start watching.
810                 std::time_t localTime = time(NULL);
811                 setLastChangeFetchTime(localTime);
812                 LogInfo("Last change fetch time: "<<getLastChangeFetchTime());
813             }
814         }
815
816         m_changeEmitters.attach(event->getEmitter());
817         event->setWatchId(event->getEmitter()->getId());
818         event->setResult(true);
819     }
820     Catch (Exception)
821     {
822         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
823         event->setResult(false);
824         event->setExceptionCode(ExceptionCodes::UnknownException);
825     }
826 }
827
828 void Calendar::OnRequestReceived(const IEventClearWatchPtr &event)
829 {
830     LogDebug("entered");
831     Try
832     {
833         m_changeEmitters.detach(event->getWatchId());
834
835         if( m_changeEmitters.size()==0 ) {
836             if( CAL_SUCCESS!=calendar_svc_unsubscribe_change(eventChangedCb) ) {
837                 ThrowMsg(PlatformException, "Can't unsubscribe the db change noti.");
838             } else {
839                 LogDebug("Platform watch cleared successfully.");
840             }
841         }
842         event->setResult(true);
843     }
844     Catch (Exception)
845     {
846         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
847         event->setResult(false);
848         event->setExceptionCode(ExceptionCodes::UnknownException);
849     }
850 }
851
852 void Calendar::OnRequestReceived(const IEventExpandEventRecurrencePtr &event)
853 {
854     LogDebug("entered");
855     const CalendarEventPtr calEvent = event->getEvent();
856     const std::time_t startDate = event->getStartDate();
857     const std::time_t endDate = event->getEndDate();
858     event->setResult(true);
859
860     Try {
861         if ( 0 >= calEvent->getRecurrenceRule()->getFrequency())
862         {
863             ThrowMsg(PlatformException, "This is not a recurring event.");
864         }
865
866         std::time_t nextStartTime = 0;
867         std::time_t nextEndTime = 0;
868
869         DPL::ScopedPtr<EventWrapper> eventWrapper(new EventWrapper(CalendarEvent::EVENT_TYPE));
870         // We must load the event from the DB in order to get the auto-calculated repeat end time.
871         eventWrapper->loadEvent(event->getEvent()->getId());
872         //eventWrapper->displayPlatformEvent();
873
874         while ( CAL_SUCCESS==calendar_svc_util_next_valid_event(eventWrapper->getPlatformEvent(), startDate, endDate, &nextStartTime, &nextEndTime) )
875         {
876             LogInfo("Found a next valid event: "<<nextStartTime);
877             DPL::ScopedPtr<EventWrapper> recurringEventWrapper(new EventWrapper(getType()));
878             recurringEventWrapper->loadEvent(calEvent->getId());
879
880             // Set distintive attributes of each instance.
881             recurringEventWrapper->getAbstractEvent()->setRecurrenceId(nextStartTime);
882             recurringEventWrapper->getAbstractEvent()->setStartTime(nextStartTime);
883             recurringEventWrapper->getAbstractEvent()->setEndTime(nextEndTime);
884
885             event->addExpandedEvent(recurringEventWrapper->getAbstractEvent());
886         }
887         LogInfo("Length of expanded events from parent: "<<event->getExpandedEventList()->size());
888
889         // Consider the detached events also.
890         cal_iter *iter = NULL;
891         cal_struct *platformEvent = NULL;
892         int parentId = event->getEvent()->getId();
893         if(CAL_SUCCESS != calendar_svc_find_event_list(getAccountId(), CAL_VALUE_INT_ORIGINAL_EVENT_ID, (void*) parentId, &iter)) {
894             LogInfo("No detached instances found.");
895         }
896
897         while (CAL_SUCCESS == calendar_svc_iter_next(iter)) {
898             platformEvent = NULL;
899             if (CAL_SUCCESS != calendar_svc_iter_get_info(iter, &platformEvent)) {
900                 ThrowMsg(PlatformException, "Can't get event info.");
901             }
902
903             int detachedEventId = calendar_svc_struct_get_int(platformEvent, CAL_VALUE_INT_INDEX);
904             std::time_t detachedStartTime = calendar_svc_struct_get_time(platformEvent, CAL_VALUE_GMT_START_DATE_TIME, CAL_TZ_FLAG_GMT);
905             std::time_t detachedEndTime = calendar_svc_struct_get_time(platformEvent, CAL_VALUE_GMT_END_DATE_TIME, CAL_TZ_FLAG_GMT);
906             if (detachedStartTime>=startDate && detachedStartTime<=endDate) {
907                 LogInfo("Found a valid detached event: "<<detachedStartTime);
908                 DPL::ScopedPtr<EventWrapper> detachedEventWrapper(new EventWrapper(getType()));
909                 detachedEventWrapper->loadEvent(detachedEventId);
910
911                 // Set the same parent uid to each instances
912                 detachedEventWrapper->getAbstractEvent()->setId(parentId);
913                 // Set distintive attributes of each instance.
914                 detachedEventWrapper->getAbstractEvent()->setRecurrenceId(detachedStartTime);
915                 detachedEventWrapper->getAbstractEvent()->setStartTime(detachedStartTime);
916                 detachedEventWrapper->getAbstractEvent()->setEndTime(detachedEndTime);
917
918                 event->addExpandedEvent(detachedEventWrapper->getAbstractEvent());
919             }
920         }
921
922         LogInfo("Length of total expanded events: "<<event->getExpandedEventList()->size());
923     }
924     Catch (Exception)
925     {
926         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
927         event->setResult(false);
928         event->setExceptionCode(ExceptionCodes::UnknownException);
929     }
930 }
931
932 }
933 }
934 }