Update change log and spec for wrt-plugins-tizen_0.4.70
[framework/web/wrt-plugins-tizen.git] / src / Calendar / JSCalendarItemProperties.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <ctime>
19 #include <CommonsJavaScript/PrivateObject.h>
20 #include <CommonsJavaScript/Converter.h>
21 #include <CommonsJavaScript/JSUtils.h>
22 #include <JSWebAPIErrorFactory.h>
23 #include <SecurityExceptions.h>
24 #include <TimeUtilConverter.h>
25 #include <JSTimeDuration.h>
26 #include <JSTZDate.h>
27 #include <JSSimpleCoordinates.h>
28 #include "EventAlarm.h"
29 #include "EventId.h"
30 #include "ICalendar.h"
31 #include "CalendarFactory.h"
32 #include <DurationProperties.h>
33 #include "JSCalendarItemProperties.h"
34 #include "CalendarConverter.h"
35 #include "JSCalendarEventId.h"
36 #include "JSCalendarAlarm.h"
37 #include "JSCalendarAttendee.h"
38 #include "JSCalendarEvent.h"
39 #include "JSCalendarTask.h"
40 #include "plugin_config.h"
41 #include <GlobalContextManager.h>
42 #include <TimeTracer.h>
43 #include <Logger.h>
44
45 using namespace WrtDeviceApis::Commons;
46 using namespace WrtDeviceApis::CommonsJavaScript;
47 using namespace DeviceAPI::Common;
48 using namespace DeviceAPI::Time;
49
50 namespace DeviceAPI {
51 namespace Calendar {
52
53 using WrtDeviceApis::Commons::UnknownException;
54 using WrtDeviceApis::Commons::NotFoundException;
55
56 #define TIZEN_CALENDAR_ITEM_PROPERTIES_ATTRIBUTENAME "CalendarItemProperties"
57
58 JSClassDefinition JSCalendarItemProperties::m_classInfo = {
59     0,
60     kJSClassAttributeNone,
61     TIZEN_CALENDAR_ITEM_PROPERTIES_ATTRIBUTENAME,
62     0,
63     m_property,
64     m_function,
65     initialize,
66     finalize,
67     NULL, //hasProperty,
68     NULL, //getProperty,
69     NULL, //setProperty,
70     NULL, //DeleteProperty,
71     NULL, //GetPropertyNames,
72     NULL, //CallAsFunction,
73     NULL, //CallAsConstructor,
74     NULL, //HasInstance,
75     NULL  //ConvertToType
76 };
77
78 JSStaticValue JSCalendarItemProperties::m_property[] = {
79     // Item Properties
80     { TIZEN_CALENDAR_ITEM_DESCRIPTION, getPropertyDescription, setPropertyDescription, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
81     { TIZEN_CALENDAR_ITEM_SUMMARY, getPropertySummary, setPropertySummary, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
82     { TIZEN_CALENDAR_ITEM_START_DATE, getPropertyStartDate, setPropertyStartDate, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
83     { TIZEN_CALENDAR_ITEM_LOCATION, getPropertyLocation, setPropertyLocation, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
84     { TIZEN_CALENDAR_ITEM_GEOLOCATION, getPropertyGeolocation, setPropertyGeolocation, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
85     { TIZEN_CALENDAR_ITEM_ORGANIZER, getPropertyOrganizer, setPropertyOrganizer, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
86     { TIZEN_CALENDAR_ITEM_VISIBILITY, getPropertyVisibility, setPropertyVisibility, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
87     { TIZEN_CALENDAR_ITEM_STATUS, getPropertyStatus, setPropertyStatus, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
88     { TIZEN_CALENDAR_ITEM_ALARMS, getPropertyAlarms, setPropertyAlarms, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
89     { TIZEN_CALENDAR_ITEM_CATEGORIES, getPropertyCategories, setPropertyCategories, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
90     { TIZEN_CALENDAR_ITEM_DURATION, getPropertyDuration, setPropertyDuration, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
91     { TIZEN_CALENDAR_ITEM_IS_ALL_DAY, getPropertyIsAllDay, setPropertyIsAllDay, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
92     { TIZEN_CALENDAR_ITEM_ATTENDEES, getPropertyAttendees, setPropertyAttendees, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
93     { TIZEN_CALENDAR_TASK_DUE_DATE, getPropertyDueDate, setPropertyDueDate, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
94     { TIZEN_CALENDAR_ITEM_PRIORITY, getPropertyPriority, setPropertyPriority, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
95     { TIZEN_CALENDAR_EVENT_END_DATE, getPropertyEndDate, setPropertyEndDate, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
96     { TIZEN_CALENDAR_EVENT_LAST_MODIFICATION_DATE, getPropertyLastModificationDate, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
97         { TIZEN_CALENDAR_ITEM_CALENDAR_ID, getPropertyCalendarId, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
98
99     { 0, 0, 0, 0 }
100 };
101
102 JSStaticFunction JSCalendarItemProperties::m_function[] = {
103     { CALENDAR_FUNCTION_API_CONVERT_TO_STRING, convertToString, kJSPropertyAttributeNone },
104     { CALENDAR_FUNCTION_API_CLONE, clone, kJSPropertyAttributeNone },
105
106     { 0, 0, 0 }
107 };
108
109 JSClassRef JSCalendarItemProperties::m_jsClassRef = JSClassCreate(JSCalendarItemProperties::getClassInfo());
110
111 void JSCalendarItemProperties::initialize(JSContextRef context,
112         JSObjectRef object)
113 {
114     if (!JSObjectGetPrivate(object)) {
115         LoggerD("Create calendar item private object.");
116         CalendarEventPtr item( new CalendarEvent() );
117         CalendarItemPropertiesPrivObject *priv = new CalendarItemPropertiesPrivObject(context, item);
118         if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
119             delete priv;
120         }
121     } else {
122         LoggerD("Private object already set.");
123     }
124 }
125
126 void JSCalendarItemProperties::finalize(JSObjectRef object)
127 {
128     CalendarItemPropertiesPrivObject *priv = static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
129     if (priv) {
130         delete priv;
131         JSObjectSetPrivate(object, NULL);
132     }
133 }
134
135 const JSClassRef JSCalendarItemProperties::getClassRef()
136 {
137     if (!m_jsClassRef) {
138         m_jsClassRef = JSClassCreate(&m_classInfo);
139     }
140     return m_jsClassRef;
141 }
142
143 const JSClassDefinition* JSCalendarItemProperties::getClassInfo()
144 {
145     return &m_classInfo;
146 }
147
148 CalendarEventPtr JSCalendarItemProperties::getPrivateObject(JSObjectRef object)
149 {
150     CalendarItemPropertiesPrivObject *priv =
151         static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
152     if (!priv) {
153         ThrowMsg(NullPointerException, "Private object is null");
154     }
155     CalendarEventPtr result = priv->getObject();
156     if (!result) {
157         ThrowMsg(NullPointerException, "Private object is null");
158     }
159     return result;
160 }
161
162 void JSCalendarItemProperties::setPrivateObject(const CalendarEventPtr &event,
163         JSContextRef ctx,
164         const JSObjectRef object)
165 {
166     Try
167     {
168         CalendarItemPropertiesPrivObject *priv =
169             static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
170         delete priv;
171         priv = new CalendarItemPropertiesPrivObject(ctx, event);
172         if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
173             delete priv;
174         }
175     }
176     Catch(Exception)
177     {
178         LoggerE("Error during replacing event object");
179     }
180 }
181
182 JSObjectRef JSCalendarItemProperties::createJSCalendarItemProperties(JSContextRef context, CalendarEventPtr item)
183 {
184     CalendarItemPropertiesPrivObject *priv = new CalendarItemPropertiesPrivObject(context, item);
185     return JSObjectMake(context, getClassRef(), priv);
186 }
187
188 JSValueRef JSCalendarItemProperties::convertToString(JSContextRef context,
189         JSObjectRef object,
190         JSObjectRef thisObject,
191         size_t argumentCount,
192         const JSValueRef arguments[],
193         JSValueRef* exception)
194 {
195         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
196     CalendarItemPropertiesPrivObject *privateObject =
197         static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(thisObject));
198
199     TIZEN_CHECK_ACCESS(context, exception, privateObject, CALENDAR_FUNCTION_API_CONVERT_TO_STRING);
200
201     Try
202     {
203         if (!privateObject) {
204             ThrowMsg(ConversionException, "Object is null.");
205         }
206
207         CalendarEventPtr item = privateObject->getObject();
208         if (!item) {
209             ThrowMsg(ConversionException, "Parameter conversion failed.");
210         }
211
212         CalendarConverter converter(context);
213
214         CalendarEvent::VObjectFormat format = CalendarEvent::UNDEFINED_FORMAT;
215         if (argumentCount>=1) {
216             format = converter.toVObjectFormat(converter.toString(arguments[0]));
217         }
218                 if (CalendarEvent::UNDEFINED_FORMAT==format) {
219             ThrowMsg(ConversionException, "Wrong parameter type.");
220         }
221
222         ICalendarPtr calendar = CalendarFactory::getInstance().createCalendarObject();
223         calendar->setType(item->getCalendarType());
224
225         IEventExportEventToStringPtr dplEvent(new IEventExportEventToString());
226         dplEvent->setEvent(item);
227         dplEvent->setFormat(format);
228         dplEvent->setForSynchronousCall();
229         calendar->exportEventToString(dplEvent);
230
231         if (dplEvent->getResult()) {
232                         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
233             return converter.toJSValueRef(dplEvent->getEventString());
234         } else {
235             ThrowMsg(UnknownException, "Converting to string failed by unknown reason.");
236         }
237     }
238     Catch(UnsupportedException)
239     {
240                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
241         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
242     }
243     Catch(InvalidArgumentException)
244     {
245                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
246         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
247     }
248     Catch(ConversionException)
249     {
250                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
251         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
252     }
253     Catch (NotFoundException)
254     {
255                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
256         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
257     }
258     Catch(Exception)
259     {
260                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
261         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
262     }
263 }
264
265 JSValueRef JSCalendarItemProperties::clone(JSContextRef context,
266         JSObjectRef object,
267         JSObjectRef thisObject,
268         size_t argumentCount,
269         const JSValueRef arguments[],
270         JSValueRef* exception)
271 {
272         TIME_TRACER_ITEM_BEGIN("clone(TASK)", 0);
273         TIME_TRACER_ITEM_BEGIN("clone(EVENT)", 0);
274     CalendarItemPropertiesPrivObject *privateObject =
275         static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(thisObject));
276
277     TIZEN_CHECK_ACCESS(context, exception, privateObject, CALENDAR_FUNCTION_API_CLONE);
278
279     Try
280     {
281         if (!privateObject) {
282             ThrowMsg(ConversionException, "Object is null.");
283         }
284
285         CalendarEventPtr item = privateObject->getObject(); // item to copy
286         if (!item) {
287             ThrowMsg(ConversionException, "Parameter conversion failed.");
288         }
289         JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
290
291         // Call the copy constructor.
292         CalendarEventPtr clonedItem( new CalendarEvent(*item));
293
294         // Reset the id.
295         clonedItem->resetId();
296         clonedItem->setRecurrenceId(UNDEFINED_ITEM_ID);
297
298                 if (CalendarEvent::TASK_TYPE==clonedItem->getCalendarType()) {
299                         TIME_TRACER_ITEM_END("clone(TASK)", 0);
300                 return JSCalendarTask::createJSCalendarTask(context, clonedItem, privateObject);
301                 } else if (CalendarEvent::EVENT_TYPE==clonedItem->getCalendarType()) {
302                         TIME_TRACER_ITEM_END("clone(EVENT)", 0);
303             // Use global context for potential async api invocation.
304             return JSCalendarEvent::createJSCalendarEvent(globalContext, clonedItem, privateObject);
305                 } else {
306                         ThrowMsg(ConversionException, "Wrong object type.");
307                 }
308     }
309     Catch(UnsupportedException)
310     {
311                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
312         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
313     }
314     Catch(InvalidArgumentException)
315     {
316                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
317         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
318     }
319     Catch(ConversionException)
320     {
321                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
322         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
323     }
324     Catch (NotFoundException)
325     {
326                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
327         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
328     }
329     Catch(Exception)
330     {
331                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
332         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
333     }
334 }
335
336 JSValueRef JSCalendarItemProperties::getPropertyDescription(JSContextRef context,
337         JSObjectRef object,
338         JSStringRef propertyName,
339         JSValueRef* exception)
340 {
341     Try
342     {
343         Converter converter(context);
344         CalendarEventPtr event = getPrivateObject(object);
345         return converter.toJSValueRef(event->getDescription());
346     }
347     Catch(Exception)
348     {
349                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
350     }
351     return JSValueMakeUndefined(context);
352 }
353
354 bool JSCalendarItemProperties::setPropertyDescription(JSContextRef context,
355         JSObjectRef object,
356         JSStringRef propertyName,
357         JSValueRef value,
358         JSValueRef* exception)
359 {
360     Try
361     {
362         Converter converter(context);
363         CalendarEventPtr event = getPrivateObject(object);
364         std::string description = converter.toString(value);
365         event->setDescription(description);
366         return true;
367     }
368     Catch(Exception)
369     {
370                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
371     }
372
373     return true;
374 }
375
376 JSValueRef JSCalendarItemProperties::getPropertySummary(JSContextRef context,
377         JSObjectRef object,
378         JSStringRef propertyName,
379         JSValueRef* exception)
380 {
381     Try
382     {
383         Converter converter(context);
384         CalendarEventPtr event = getPrivateObject(object);
385         return converter.toJSValueRef(event->getSubject());
386     }
387     Catch(Exception)
388     {
389                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
390     }
391     return JSValueMakeUndefined(context);
392 }
393
394 bool JSCalendarItemProperties::setPropertySummary(JSContextRef context,
395         JSObjectRef object,
396         JSStringRef propertyName,
397         JSValueRef value,
398         JSValueRef* exception)
399 {
400     Try
401     {
402         Converter converter(context);
403         CalendarEventPtr event = getPrivateObject(object);
404         std::string subject = converter.toString(value);
405         event->setSubject(subject);
406         return true;
407     }
408     Catch(Exception)
409     {
410                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
411     }
412
413     return true;
414 }
415
416 JSValueRef JSCalendarItemProperties::getPropertyStartDate(JSContextRef context,
417         JSObjectRef object,
418         JSStringRef propertyName,
419         JSValueRef* exception)
420 {
421     Try
422     {
423         CalendarItemPropertiesPrivObject *privateObject = static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
424
425         TimeUtilConverter timeConverter(context);
426         CalendarEventPtr item = privateObject->getObject();
427
428         LoggerI("start time before converted to TZDate: "<<item->getStartTime()<<", time zone: "<<item->getTimeZone());
429         if (UNDEFINED_TIME==item->getStartTime()) {
430             return JSValueMakeNull(context);
431         } else {
432             return timeConverter.toJSValueRefTZDate((double)(item->getStartTime()*1000.0), item->getTimeZone());
433         }
434     }
435     Catch(Exception)
436     {
437                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
438     }
439
440     return JSValueMakeUndefined(context);
441 }
442
443 bool JSCalendarItemProperties::setPropertyStartDate(JSContextRef context,
444         JSObjectRef object,
445         JSStringRef propertyName,
446         JSValueRef value,
447         JSValueRef* exception)
448 {
449     Try
450     {
451         CalendarEventPtr item = getPrivateObject(object);
452
453                 if (JSValueIsNull(context, value)) {
454                         item->setStartTime(UNDEFINED_TIME);
455                         return true;
456                 } else if (!JSValueIsObjectOfClass(context, value, JSTZDate::getClassRef())) {
457                         ThrowMsg(ConversionException, "Wrong parameter type.");
458                 }
459
460         TimeUtilConverter timeConverter(context);
461
462         long long int startTime = (long long int) (timeConverter.getTimeInMilliseconds(value)/1000);
463         item->setStartTime(startTime);
464
465         std::string timeZone = timeConverter.getPropertiesInTZDate(value).timezone;
466         item->setTimeZone(timeZone);
467
468         return true;
469     }
470     Catch(Exception)
471     {
472                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
473     }
474
475     return true;
476 }
477
478 JSValueRef JSCalendarItemProperties::getPropertyLocation(JSContextRef context,
479         JSObjectRef object,
480         JSStringRef propertyName,
481         JSValueRef* exception)
482 {
483     Try
484     {
485         Converter converter(context);
486         CalendarEventPtr event = getPrivateObject(object);
487         return converter.toJSValueRef(event->getLocation());
488     }
489     Catch(Exception)
490     {
491                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
492     }
493     return JSValueMakeUndefined(context);
494 }
495
496 bool JSCalendarItemProperties::setPropertyLocation(JSContextRef context,
497         JSObjectRef object,
498         JSStringRef propertyName,
499         JSValueRef value,
500         JSValueRef* exception)
501 {
502     Try
503     {
504         Converter converter(context);
505         CalendarEventPtr event = getPrivateObject(object);
506         std::string location = converter.toString(value);
507         event->setLocation(location);
508         return true;
509     }
510     Catch(Exception)
511     {
512                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
513     }
514
515     return true;
516 }
517
518 JSValueRef JSCalendarItemProperties::getPropertyCategories(JSContextRef context,
519         JSObjectRef object,
520         JSStringRef propertyName,
521         JSValueRef* exception)
522 {
523     Try
524     {
525             CalendarEventPtr item = getPrivateObject(object);
526                 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
527
528         CalendarConverter converter(globalContext);
529
530                 if(item->getCategoriesJSRef()) {
531                         return item->getCategoriesJSRef();
532                 } else {
533                         LoggerD("Create a JS object for categories.");
534                 StringArrayPtr categories = item->getCategories();
535                         JSValueRef jsCategories = converter.toJSValueRefStringArray(categories);
536                         item->setCategoriesJSRef(converter.toJSObjectRef(jsCategories));
537
538                         JSValueProtect(globalContext, jsCategories);
539                         item->setContext(globalContext);
540             return jsCategories;
541                 }
542     }
543     Catch(Exception)
544     {
545                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
546     }
547     return JSValueMakeUndefined(context);
548 }
549
550 bool JSCalendarItemProperties::setPropertyCategories(JSContextRef context,
551         JSObjectRef object,
552         JSStringRef propertyName,
553         JSValueRef value,
554         JSValueRef* exception)
555 {
556     Try
557     {
558         CalendarEventPtr item = getPrivateObject(object);
559         CalendarConverter converter(context);
560                 item->setCategories(converter.toStringArray(value));
561
562                 if(item->getCategoriesJSRef()) {
563                         LoggerI("Replace a JS object for categories.");
564                         JSValueUnprotect(item->getContext(), item->getCategoriesJSRef());
565                         item->setCategoriesJSRef(converter.toJSObjectRef(value));
566                         JSValueProtect(item->getContext(), value);
567                 }
568
569         return true;
570     }
571     Catch(Exception)
572     {
573                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
574     }
575
576     return true;
577 }
578
579 JSValueRef JSCalendarItemProperties::getPropertyStatus(JSContextRef context,
580         JSObjectRef object,
581         JSStringRef propertyName,
582         JSValueRef* exception)
583 {
584     Try
585     {
586         CalendarConverter converter(context);
587         CalendarEventPtr event = getPrivateObject(object);
588         std::string status = converter.toTizenValue(event->getStatus());
589         return converter.toJSValueRef(status);
590     }
591     Catch(Exception)
592     {
593                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
594     }
595     return JSValueMakeUndefined(context);
596 }
597
598 bool JSCalendarItemProperties::setPropertyStatus(JSContextRef context,
599         JSObjectRef object,
600         JSStringRef propertyName,
601         JSValueRef value,
602         JSValueRef* exception)
603 {
604     CalendarEventPtr event(NULL);
605     Try
606     {
607         event = getPrivateObject(object);
608         CalendarConverter converter(context);
609         CalendarEvent::EventStatus status =
610             converter.toEventStatus(converter.toString(value));
611         event->setStatus(status);
612         return true;
613     }
614     Catch(Exception)
615     {
616                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
617     }
618
619     return true;
620 }
621
622 JSValueRef JSCalendarItemProperties::getPropertyAlarms(JSContextRef context,
623         JSObjectRef object,
624         JSStringRef propertyName,
625         JSValueRef* exception)
626 {
627     Try
628     {
629         CalendarEventPtr item = getPrivateObject(object);
630
631                 if(item->getAlarmsJSRef()) {
632                         return item->getAlarmsJSRef();
633                 } else {
634                         LoggerI("Create a JS object for alarms.");
635                     JSObjectRef jsAlarms = JSCreateArrayObject(context, 0, NULL);
636                     if (NULL == jsAlarms) {
637                         ThrowMsg(NullPointerException, "Cannot create an array object.");
638                     }
639                     for( unsigned int i=0; i<item->getAlarms()->size(); i++) {
640                         if (!JSSetArrayElement(context, jsAlarms, i, JSCalendarAlarm::createJSCalendarAlarm(context, item->getAlarms()->at(i)))) {
641                            ThrowMsg(UnknownException, "Cannot insert a value into array.");
642                         }
643                     }
644
645                         JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
646                 CalendarConverter converter(globalContext);
647                         item->setAlarmsJSRef(converter.toJSObjectRef(jsAlarms));
648                         JSValueProtect(globalContext, jsAlarms);
649                         item->setContext(globalContext);
650
651                     return jsAlarms;
652                 }
653     }
654     Catch(Exception)
655     {
656                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
657     }
658     return JSValueMakeUndefined(context);
659 }
660
661 bool JSCalendarItemProperties::setPropertyAlarms(JSContextRef context,
662         JSObjectRef object,
663         JSStringRef propertyName,
664         JSValueRef value,
665         JSValueRef* exception)
666 {
667     CalendarEventPtr item(NULL);
668     Try
669     {
670         item = getPrivateObject(object);
671         CalendarConverter converter(context);
672
673         EventAlarmListPtr alarms = converter.toVectorOfEventAlarmsFromReference(value);
674
675         item->setAlarms(alarms);
676
677                 if(item->getAlarmsJSRef()) {
678                         LoggerI("Replace a JS object for alarms.");
679                         JSValueUnprotect(item->getContext(), item->getAlarmsJSRef());
680                         item->setAlarmsJSRef(converter.toJSObjectRef(value));
681                         JSValueProtect(item->getContext(), value);
682                 }
683
684         return true;
685     }
686     Catch(Exception)
687     {
688                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
689     }
690
691     return true;
692 }
693
694 JSValueRef JSCalendarItemProperties::getPropertyOrganizer(JSContextRef context,
695         JSObjectRef object,
696         JSStringRef propertyName,
697         JSValueRef* exception)
698 {
699     Try
700     {
701         Converter converter(context);
702         CalendarEventPtr event = getPrivateObject(object);
703         return converter.toJSValueRef(event->getOrganizer());
704     }
705     Catch(Exception)
706     {
707                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
708     }
709     return JSValueMakeUndefined(context);
710 }
711
712 bool JSCalendarItemProperties::setPropertyOrganizer(JSContextRef context,
713         JSObjectRef object,
714         JSStringRef propertyName,
715         JSValueRef value,
716         JSValueRef* exception)
717 {
718     Try
719     {
720         Converter converter(context);
721         CalendarEventPtr event = getPrivateObject(object);
722         std::string organizer = converter.toString(value);
723         event->setOrganizer(organizer);
724         return true;
725     }
726     Catch(Exception)
727     {
728                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
729     }
730
731     return true;
732 }
733
734 JSValueRef JSCalendarItemProperties::getPropertyVisibility(JSContextRef context,
735         JSObjectRef object,
736         JSStringRef propertyName,
737         JSValueRef* exception)
738 {
739     Try
740     {
741         CalendarConverter converter(context);
742         CalendarEventPtr event = getPrivateObject(object);
743         std::string visibility = converter.toTizenValue(event->getVisibility());
744         return converter.toJSValueRef(visibility);
745     }
746     Catch(Exception)
747     {
748                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
749     }
750     return JSValueMakeUndefined(context);
751 }
752
753 bool JSCalendarItemProperties::setPropertyVisibility(JSContextRef context,
754         JSObjectRef object,
755         JSStringRef propertyName,
756         JSValueRef value,
757         JSValueRef* exception)
758 {
759     CalendarEventPtr event(NULL);
760     Try
761     {
762         event = getPrivateObject(object);
763         CalendarConverter converter(context);
764         CalendarEvent::EventVisibility visibility =
765             converter.toEventVisibility(converter.toString(value));
766         event->setVisibility(visibility);
767         return true;
768     }
769     Catch(Exception)
770     {
771                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
772     }
773
774     return true;
775 }
776
777 JSValueRef JSCalendarItemProperties::getPropertyGeolocation(JSContextRef context,
778         JSObjectRef object,
779         JSStringRef propertyName,
780         JSValueRef* exception)
781 {
782     Try
783     {
784         CalendarEventPtr item = getPrivateObject(object);
785         if( UNDEFINED_GEO==item->getGeolocation()->getLatitude() ) {
786                         return JSValueMakeUndefined(context);
787                 } else {
788                         return DeviceAPI::Tizen::JSSimpleCoordinates::createJSObject(context, item->getGeolocation());
789                 }
790     }
791     Catch(Exception)
792     {
793                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
794     }
795
796     return JSValueMakeUndefined(context);
797 }
798
799 bool JSCalendarItemProperties::setPropertyGeolocation(JSContextRef context,
800         JSObjectRef object,
801         JSStringRef propertyName,
802         JSValueRef value,
803         JSValueRef* exception)
804 {
805     Try
806     {
807         CalendarEventPtr item = getPrivateObject(object);
808
809                 if (JSValueIsNull(context, value)) {
810                 item->getGeolocation()->setLatitude(UNDEFINED_GEO);
811                 item->getGeolocation()->setLongitude(UNDEFINED_GEO);
812                 } else {
813                 DeviceAPI::Tizen::SimpleCoordinatesPtr geoLocation = DeviceAPI::Tizen::JSSimpleCoordinates::getSimpleCoordinates(context, value);
814
815                 item->setGeolocation(geoLocation);
816                 }
817         return true;
818     }
819     Catch(Exception)
820     {
821                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
822     }
823
824     return true;
825 }
826
827 JSValueRef JSCalendarItemProperties::getPropertyDuration(JSContextRef context,
828         JSObjectRef object,
829         JSStringRef propertyName,
830         JSValueRef* exception)
831 {
832     Try
833     {
834         CalendarEventPtr item = getPrivateObject(object);
835
836                 if(UNDEFINED_TIME!=item->getDuration()->length) {
837                         LoggerD("Duration length: "<<item->getDuration()->length<<", unit: "<<item->getDuration()->unit);
838                         return JSTimeDuration::createJSObject(context, item->getDuration());
839                 } else {
840             return JSValueMakeNull(context);
841                 }
842     }
843     Catch(Exception)
844     {
845                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
846     }
847     return JSValueMakeUndefined(context);
848 }
849
850 bool JSCalendarItemProperties::setPropertyDuration(JSContextRef context,
851         JSObjectRef object,
852         JSStringRef propertyName,
853         JSValueRef value,
854         JSValueRef* exception)
855 {
856     Try
857     {
858         CalendarEventPtr item = getPrivateObject(object);
859
860                 if (JSValueIsNull(context, value)) {
861                         DurationPropertiesPtr duration(new DeviceAPI::Time::DurationProperties());
862                         item->setDuration(duration);
863                         item->setEndTime(UNDEFINED_TIME);
864                         return true;
865                 }
866
867         TimeUtilConverter timeUtilConverter(context);
868
869                 DurationPropertiesPtr duration = timeUtilConverter.getDuration(value);
870         LoggerD("length: "<<duration->length<< ", unit:" <<duration->unit);
871                 item->setDuration(duration);
872
873                 item->setEndTime(UNDEFINED_TIME);
874
875         return true;
876     }
877     Catch(Exception)
878     {
879                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
880     }
881
882     return true;
883 }
884
885 JSValueRef JSCalendarItemProperties::getPropertyIsAllDay(JSContextRef context,
886         JSObjectRef object,
887         JSStringRef propertyName,
888         JSValueRef* exception)
889 {
890     Try
891     {
892         CalendarConverter converter(context);
893         CalendarEventPtr event = getPrivateObject(object);
894         return converter.toJSValueRef(event->getIsAllDay());
895     }
896     Catch(Exception)
897     {
898                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
899     }
900     return JSValueMakeUndefined(context);
901 }
902
903 bool JSCalendarItemProperties::setPropertyIsAllDay(JSContextRef context,
904         JSObjectRef object,
905         JSStringRef propertyName,
906         JSValueRef value,
907         JSValueRef* exception)
908 {
909     Try
910     {
911         CalendarEventPtr event = getPrivateObject(object);
912         Converter converter(context);
913         event->setIsAllDay(converter.toBool(value));
914         return true;
915     }
916     Catch(Exception)
917     {
918                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
919     }
920
921     return true;
922 }
923
924 JSValueRef JSCalendarItemProperties::getPropertyAttendees(JSContextRef context,
925         JSObjectRef object,
926         JSStringRef propertyName,
927         JSValueRef* exception)
928 {
929     Try
930     {
931         CalendarEventPtr item = getPrivateObject(object);
932
933                 if(item->getAttendeesJSRef()) {
934                         return item->getAttendeesJSRef();
935                 } else {
936                         LoggerI("Create a JS object for attendees.");
937             JSObjectRef jsAttendees = JSCreateArrayObject(context, 0, NULL);
938             if (NULL == jsAttendees) {
939                 ThrowMsg(NullPointerException, "Cannot create an array object.");
940             }
941                 EventAttendeeListPtr attendees = item->getAttendees();
942             for(unsigned int i=0; i<attendees->size(); i++) {
943                 if (!JSSetArrayElement(context, jsAttendees, i, JSCalendarAttendee::createJSCalendarAttendee(context, attendees->at(i)))) {
944                    ThrowMsg(UnknownException, "Cannot insert a value into array.");
945                 }
946             }
947
948                         JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
949                 CalendarConverter converter(globalContext);
950                         item->setAttendeesJSRef(converter.toJSObjectRef(jsAttendees));
951                         JSValueProtect(globalContext, jsAttendees);
952                         item->setContext(globalContext);
953
954                         return jsAttendees;
955         }
956     }
957     Catch(Exception)
958     {
959                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
960     }
961     return JSValueMakeUndefined(context);
962 }
963
964 bool JSCalendarItemProperties::setPropertyAttendees(JSContextRef context,
965         JSObjectRef object,
966         JSStringRef propertyName,
967         JSValueRef value,
968         JSValueRef* exception)
969 {
970     Try
971     {
972         CalendarEventPtr item = getPrivateObject(object);
973         CalendarConverter converter(context);
974         item->setAttendees(converter.toVectorOfAttendeesFromReference(value));
975
976                 if(item->getAttendeesJSRef()) {
977                         LoggerI("Replace a JS object for attendees.");
978                         JSValueUnprotect(item->getContext(), item->getAttendeesJSRef());
979                         item->setAttendeesJSRef(converter.toJSObjectRef(value));
980                         JSValueProtect(item->getContext(), value);
981                 }
982
983         return true;
984     }
985     Catch(Exception)
986     {
987                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
988     }
989
990     return true;
991 }
992
993 JSValueRef JSCalendarItemProperties::getPropertyDueDate(JSContextRef context,
994         JSObjectRef object,
995         JSStringRef propertyName,
996         JSValueRef* exception)
997 {
998     Try
999         {
1000         CalendarItemPropertiesPrivObject *privateObject =
1001             static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
1002         CalendarEventPtr task = privateObject->getObject();
1003         if(CalendarEvent::TASK_TYPE != task->getCalendarType()) {
1004             return JSValueMakeUndefined(context);
1005         }
1006         if (!task) {
1007             ThrowMsg(NullPointerException, "Task object is NULL.");
1008         }
1009
1010         if (UNDEFINED_TIME==task->getEndTime()) {
1011             return JSValueMakeNull(context);
1012         } else {
1013             TimeUtilConverter timeConverter(context);
1014             return timeConverter.toJSValueRefTZDate((double)(task->getEndTime()*1000.0), task->getTimeZone());
1015         }
1016     }
1017     Catch(Exception)
1018     {
1019                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1020     }
1021     return JSValueMakeUndefined(context);
1022 }
1023
1024 bool JSCalendarItemProperties::setPropertyDueDate(JSContextRef context,
1025         JSObjectRef object,
1026         JSStringRef propertyName,
1027         JSValueRef value,
1028         JSValueRef* exception)
1029 {
1030     Try
1031     {
1032         CalendarEventPtr task = getPrivateObject(object);
1033         if (!task) {
1034             ThrowMsg(NullPointerException, "Task object is NULL.");
1035         }
1036         if(CalendarEvent::TASK_TYPE != task->getCalendarType()) {
1037             ThrowMsg(InvalidArgumentException, "Wrong type of calendar.");
1038         }
1039
1040                 if (JSValueIsNull(context, value)) {
1041                         task->setEndTime(UNDEFINED_TIME);
1042                         return true;
1043         } else if (!JSValueIsObjectOfClass(context, value, JSTZDate::getClassRef())) {
1044             ThrowMsg(ConversionException, "Wrong parameter type.");
1045         }
1046
1047         TimeUtilConverter converter(context);
1048         long long int dueDate = (long long int) (converter.getTimeInMilliseconds(value)/1000);
1049
1050         task->setEndTime(dueDate);
1051
1052                 DurationPropertiesPtr duration(new DeviceAPI::Time::DurationProperties());
1053                 task->setDuration(duration);
1054
1055         if( task->getTimeZone().empty() ) {
1056             std::string timeZone = converter.getPropertiesInTZDate(value).timezone;
1057             task->setTimeZone(timeZone);
1058         }
1059         return true;
1060     }
1061     Catch(Exception)
1062     {
1063                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1064     }
1065
1066     return true;
1067 }
1068
1069 JSValueRef JSCalendarItemProperties::getPropertyPriority(JSContextRef context,
1070         JSObjectRef object,
1071         JSStringRef propertyName,
1072         JSValueRef* exception)
1073 {
1074     Try
1075     {
1076         CalendarConverter converter(context);
1077         CalendarEventPtr item = getPrivateObject(object);
1078         if (!item) {
1079             ThrowMsg(NullPointerException, "Item object is NULL.");
1080         }
1081
1082         std::string priority = converter.toTizenValue(item->getPriority());
1083         return converter.toJSValueRef(priority);
1084     }
1085     Catch(Exception)
1086     {
1087                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1088     }
1089     return JSValueMakeUndefined(context);
1090 }
1091
1092 bool JSCalendarItemProperties::setPropertyPriority(JSContextRef context,
1093         JSObjectRef object,
1094         JSStringRef propertyName,
1095         JSValueRef value,
1096         JSValueRef* exception)
1097 {
1098     CalendarEventPtr item = getPrivateObject(object);
1099     Try
1100     {
1101         CalendarConverter converter(context);
1102         CalendarEvent::TaskPriority priority =
1103             converter.toTaskPriority(converter.toString(value));
1104         item->setPriority(priority);
1105         return true;
1106     }
1107     Catch(Exception)
1108     {
1109                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1110     }
1111
1112     return true;
1113 }
1114
1115 JSValueRef JSCalendarItemProperties::getPropertyEndDate(JSContextRef context,
1116         JSObjectRef object,
1117         JSStringRef propertyName,
1118         JSValueRef* exception)
1119 {
1120     Try
1121     {
1122         CalendarItemPropertiesPrivObject *privateObject =
1123             static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
1124         CalendarEventPtr event = privateObject->getObject();
1125         if(CalendarEvent::EVENT_TYPE != event->getCalendarType()) {
1126             return JSValueMakeUndefined(context);
1127         }
1128         if (!event) {
1129             ThrowMsg(NullPointerException, "Event object is NULL.");
1130         }
1131
1132         if (UNDEFINED_TIME==event->getEndTime()) {
1133             return JSValueMakeNull(context);
1134         } else {
1135             TimeUtilConverter timeConverter(context);
1136             return timeConverter.toJSValueRefTZDate((double)(event->getEndTime()*1000.0), event->getTimeZone());
1137         }
1138     }
1139     Catch(Exception)
1140     {
1141                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1142     }
1143     return JSValueMakeUndefined(context);
1144 }
1145
1146 bool JSCalendarItemProperties::setPropertyEndDate(JSContextRef context,
1147         JSObjectRef object,
1148         JSStringRef propertyName,
1149         JSValueRef value,
1150         JSValueRef* exception)
1151 {
1152     Try
1153     {
1154         CalendarEventPtr event = getPrivateObject(object);
1155         if (!event) {
1156             ThrowMsg(NullPointerException, "Event object is NULL.");
1157         }
1158         if(CalendarEvent::EVENT_TYPE != event->getCalendarType()) {
1159             ThrowMsg(InvalidArgumentException, "Wrong calendar type.");
1160         }
1161
1162                 if (JSValueIsNull(context, value)) {
1163                         event->setEndTime(UNDEFINED_TIME);
1164                         return true;
1165                 } else if (!JSValueIsObjectOfClass(context, value, JSTZDate::getClassRef())) {
1166             ThrowMsg(ConversionException, "Wrong parameter type.");
1167         }
1168
1169         TimeUtilConverter converter(context);
1170         long long int endDate = (long long int) (converter.getTimeInMilliseconds(value)/1000);
1171
1172         event->setEndTime(endDate);
1173
1174                 DurationPropertiesPtr duration(new DeviceAPI::Time::DurationProperties());
1175                 event->setDuration(duration);
1176
1177         if( event->getTimeZone().empty() ) {
1178             std::string timeZone = converter.getPropertiesInTZDate(value).timezone;
1179             event->setTimeZone(timeZone);
1180         }
1181         return true;
1182     }
1183     Catch(Exception)
1184     {
1185                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1186     }
1187
1188     return true;
1189 }
1190
1191 JSValueRef JSCalendarItemProperties::getPropertyLastModificationDate(JSContextRef context,
1192         JSObjectRef object,
1193         JSStringRef propertyName,
1194         JSValueRef* exception)
1195 {
1196     Try
1197     {
1198         CalendarEventPtr item = getPrivateObject(object);
1199         if (!item) {
1200             ThrowMsg(NullPointerException, "Item object is NULL.");
1201         }
1202
1203         if (UNDEFINED_TIME==item->getLastModifiedDate()) {
1204             return JSValueMakeNull(context);
1205         } else {
1206             TimeUtilConverter timeConverter(context);
1207             return timeConverter.toJSValueRefTZDate((double)(item->getLastModifiedDate()*1000.0), item->getTimeZone());
1208         }
1209     }
1210     Catch(Exception)
1211     {
1212                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1213     }
1214     return JSValueMakeUndefined(context);
1215 }
1216
1217 JSValueRef JSCalendarItemProperties::getPropertyCalendarId(JSContextRef context,
1218         JSObjectRef object,
1219         JSStringRef propertyName,
1220         JSValueRef* exception)
1221 {
1222     Try
1223     {
1224         CalendarEventPtr item = getPrivateObject(object);
1225
1226             if (UNDEFINED_CALENDAR_ID==item->getCalendarId()) {
1227             return JSValueMakeNull(context);
1228             } else {
1229                 CalendarConverter converter(context);
1230                         std::stringstream ss;
1231                         ss<<item->getCalendarId();
1232                         return converter.toJSValueRef(ss.str());
1233             }
1234
1235     }
1236     Catch(Exception)
1237     {
1238                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
1239     }
1240     return JSValueMakeUndefined(context);
1241 }
1242
1243 }
1244 }