2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <CommonsJavaScript/PrivateObject.h>
20 #include <CommonsJavaScript/Converter.h>
21 #include <CommonsJavaScript/JSUtils.h>
22 #include <CommonsJavaScript/Utils.h>
23 #include <CommonsJavaScript/Validator.h>
24 #include <CommonsJavaScript/JSCallbackManager.h>
26 #include "JSCalendarEvent.h"
27 #include "JSCalendarItemProperties.h"
28 #include "CalendarConverter.h"
29 #include "JSCalendarEventId.h"
30 #include "JSCalendarRecurrenceRule.h"
31 #include "plugin_config.h"
32 #include "CalendarResponseDispatcher.h"
33 #include <TimeUtilConverter.h>
35 #include <JSWebAPIErrorFactory.h>
36 #include <SecurityExceptions.h>
37 #include <GlobalContextManager.h>
38 #include <TimeTracer.h>
42 using namespace WrtDeviceApis::Commons;
43 using namespace WrtDeviceApis::CommonsJavaScript;
44 using namespace DeviceAPI::Common;
45 using namespace DeviceAPI::Time;
50 using WrtDeviceApis::Commons::UnknownException;
51 using WrtDeviceApis::Commons::NotFoundException;
53 JSClassDefinition JSCalendarEvent::m_classInfo = {
55 kJSClassAttributeNone,
56 TIZEN_INTERFACE_CALENDAR_EVENT,
57 JSCalendarItemProperties::getClassRef(),
65 NULL, //DeleteProperty,
66 NULL, //GetPropertyNames,
67 NULL, //CallAsFunction,
73 JSStaticValue JSCalendarEvent::m_property[] = {
74 { TIZEN_CALENDAR_EVENT_ID, getPropertyId, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
75 { TIZEN_CALENDAR_EVENT_IS_DETACHED, getPropertyIsDetached, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
76 { TIZEN_CALENDAR_EVENT_AVAILABILITY, getPropertyAvailability, setPropertyAvailability, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
77 { TIZEN_CALENDAR_EVENT_RECURRENCE_RULE, getPropertyRecurrenceRule, setPropertyRecurrenceRule, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
82 JSStaticFunction JSCalendarEvent::m_function[] = {
83 { CALENDAR_FUNCTION_API_EXPAND_RECURRENCE, expandRecurrence, kJSPropertyAttributeNone },
88 JSClassRef JSCalendarEvent::m_jsClassRef = JSClassCreate(JSCalendarEvent::getClassInfo());
90 ICalendarPtr JSCalendarEvent::m_calendar;
92 void JSCalendarEvent::initialize(JSContextRef context,
95 if (!JSObjectGetPrivate(object)) {
96 LoggerD("Create calendar event private object.");
97 CalendarEventPtr event( new CalendarEvent() );
98 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
99 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
103 LoggerD("Private object already set.");
106 if (NULL==m_calendar) {
107 m_calendar = CalendarFactory::getInstance().createCalendarObject();
108 m_calendar->setType(CalendarEvent::EVENT_TYPE);
109 LoggerD("Static calendar for event created.");
113 void JSCalendarEvent::finalize(JSObjectRef object)
115 CalendarEventPrivObject* priv = static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
118 JSObjectSetPrivate(object, NULL);
122 JSObjectRef DLL_EXPORT JSCalendarEvent::constructor(JSContextRef context,
123 JSObjectRef constructor,
124 size_t argumentCount,
125 const JSValueRef arguments[],
126 JSValueRef* exception)
130 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
132 CalendarConverter converter(globalContext);
133 CalendarEventPtr event;
135 if (argumentCount==0) {
136 CalendarEventPtr result(new CalendarEvent());
138 } else if (argumentCount==1) {
139 LoggerI("eventInitDict case");
140 if (JSValueIsUndefined(context, arguments[0]) || JSValueIsNull(context, arguments[0])) {
141 CalendarEventPtr result(new CalendarEvent());
143 } else if (JSValueIsObject(context, arguments[0])) {
144 event = converter.toItem(arguments[0], false);
146 ThrowMsg(ConversionException, "Parameter conversion failed.");
149 ThrowMsg(ConversionException, "Parameter conversion failed.");
151 } else if (argumentCount>=2) {
152 LoggerI("event stringRepresentation case");
153 std::string eventStr;
154 CalendarEvent::VObjectFormat format = CalendarEvent::UNDEFINED_FORMAT;
155 eventStr = converter.toString(arguments[0]);
156 format = converter.toVObjectFormat(converter.toString(arguments[1]));
158 if (NULL==m_calendar) {
159 m_calendar = CalendarFactory::getInstance().createCalendarObject();
160 m_calendar->setType(CalendarEvent::EVENT_TYPE);
161 LoggerD("Static calendar for event created.");
164 IEventCreateEventFromStringPtr dplEvent(new IEventCreateEventFromString());
165 dplEvent->setEventString(eventStr);
166 dplEvent->setFormat(format);
167 dplEvent->setForSynchronousCall();
168 m_calendar->createEventFromString(dplEvent);
170 // Process the returned object.
171 if (dplEvent->getResult()) {
172 LoggerI("Successfully created an event.");
173 event = dplEvent->getEvent();
175 if (dplEvent->getExceptionCode()==ExceptionCodes::InvalidArgumentException) {
176 ThrowMsg(InvalidArgumentException, "Wrong string to convert.");
178 ThrowMsg(UnknownException, "Converting string failed.");
183 return createJSCalendarEvent(globalContext, event);
185 Catch(UnsupportedException)
187 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
188 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
190 Catch(InvalidArgumentException)
192 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
193 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
195 Catch(ConversionException)
197 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
198 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
202 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
203 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
207 JSObjectRef JSCalendarEvent::createJSCalendarEvent(JSContextRef context, CalendarEventPtr event)
209 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
210 return JSObjectMake(context, getClassRef(), priv);
213 const JSClassRef DLL_EXPORT JSCalendarEvent::getClassRef()
216 m_jsClassRef = JSClassCreate(&m_classInfo);
221 const JSClassDefinition* JSCalendarEvent::getClassInfo()
226 CalendarEventPtr JSCalendarEvent::getPrivateObject(JSObjectRef object)
228 CalendarEventPrivObject *priv =
229 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
231 ThrowMsg(NullPointerException, "Private object is null");
233 CalendarEventPtr result = priv->getObject();
235 ThrowMsg(NullPointerException, "Private object is null");
240 void JSCalendarEvent::setPrivateObject(const CalendarEventPtr &event,
242 const JSObjectRef object)
246 CalendarEventPrivObject *priv =
247 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
249 priv = new CalendarEventPrivObject(ctx, event);
250 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
256 LoggerE("Error during replacing event object");
260 JSValueRef JSCalendarEvent::expandRecurrence(JSContextRef context,
262 JSObjectRef thisObject,
263 size_t argumentCount,
264 const JSValueRef arguments[],
265 JSValueRef* exception)
267 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
268 CalendarEventPrivObject *privateObject =
269 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(thisObject));
271 AceSecurityStatus status = CALENDAR_CHECK_ACCESS(CALENDAR_FUNCTION_API_EXPAND_RECURRENCE);
273 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
277 if (!privateObject) {
278 ThrowMsg(ConversionException, "Object is null.");
281 CalendarEventPtr event = privateObject->getObject();
283 ThrowMsg(ConversionException, "Parameter conversion failed.");
286 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
287 CalendarConverter converter(context);
289 std::time_t startDate = 0;
290 std::time_t endDate = INT_MAX; // about 60 years in 4 bytes system.
291 TimeUtilConverter timeConverter(context);
292 if (argumentCount>=1) {
293 if (JSValueIsObjectOfClass(context, arguments[0], JSTZDate::getClassRef())) {
294 startDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[0])/1000);
295 LoggerI("startDate: "<<startDate);
297 ThrowMsg(ConversionException, "Wrong first parameter type.");
300 if (argumentCount>=2) {
301 if (JSValueIsObjectOfClass(context, arguments[1], JSTZDate::getClassRef())) {
302 endDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[1])/1000);
303 LoggerI("endDate: "<<endDate);
305 ThrowMsg(ConversionException, "Wrong second parameter type.");
309 JSValueRef onError = argumentCount > 3 ? converter.toFunctionOrNull(arguments[3]) : NULL;
311 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext, NULL, onError);
313 Validator validator(context);
314 if (validator.isCallback(arguments[2])) {
315 cbm->setOnSuccess(arguments[2]);
317 ThrowMsg(ConversionException, "Wrong third parameter type.");
320 cbm->setObject(thisObject);
322 LoggerD("Proceed the expand event to the platform.");
324 IEventExpandEventRecurrencePtr dplEvent(new IEventExpandEventRecurrence());
325 dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(cbm));
326 dplEvent->setForAsynchronousCall(&CalendarResponseDispatcher::getInstance());
327 dplEvent->setEvent(event);
328 dplEvent->setStartDate(startDate);
329 dplEvent->setEndDate(endDate);
330 m_calendar->expandEventRecurrence(dplEvent);
332 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
333 return JSValueMakeUndefined(context);
335 Catch(UnsupportedException)
337 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
338 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
340 Catch(InvalidArgumentException)
342 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
343 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
345 Catch(ConversionException)
347 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
348 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
350 Catch (NotFoundException)
352 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
353 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
357 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
358 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
362 JSValueRef JSCalendarEvent::getPropertyId(JSContextRef context,
364 JSStringRef propertyName,
365 JSValueRef* exception)
369 CalendarEventPrivObject *privateObject = static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
370 CalendarEventPtr event = privateObject->getObject();
372 EventIdPtr eventId( new EventId() );
374 if (UNDEFINED_ITEM_ID==event->getId()) {
375 return JSValueMakeNull(context);
377 eventId->setUId(event->getUId());
380 std::stringstream ss;
381 std::time_t rid = event->getRecurrenceId();
383 eventId->setRecurrenceId(ss.str());
384 return JSCalendarEventId::createJSCalendarEventId(context, eventId);
388 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
390 return JSValueMakeUndefined(context);
393 JSValueRef JSCalendarEvent::getPropertyIsDetached(JSContextRef context,
395 JSStringRef propertyName,
396 JSValueRef* exception)
400 CalendarEventPtr event = getPrivateObject(object);
401 Converter converter(context);
402 return converter.toJSValueRef(event->getIsDetached());
406 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
408 return JSValueMakeUndefined(context);
411 JSValueRef JSCalendarEvent::getPropertyAvailability(JSContextRef context,
413 JSStringRef propertyName,
414 JSValueRef* exception)
418 CalendarConverter converter(context);
419 CalendarEventPtr event = getPrivateObject(object);
420 std::string availability = converter.toTizenValue(event->getAvailability());
421 return converter.toJSValueRef(availability);
425 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
427 return JSValueMakeUndefined(context);
430 bool JSCalendarEvent::setPropertyAvailability(JSContextRef context,
432 JSStringRef propertyName,
434 JSValueRef* exception)
436 CalendarEventPtr event(NULL);
439 event = getPrivateObject(object);
440 CalendarConverter converter(context);
441 CalendarEvent::EventAvailability availability = converter.toEventAvailability(converter.toString(value));
442 event->setAvailability(availability);
447 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
453 JSValueRef JSCalendarEvent::getPropertyRecurrenceRule(JSContextRef context,
455 JSStringRef propertyName,
456 JSValueRef* exception)
460 CalendarItemPropertiesPrivObject *priv = static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
462 CalendarEventPtr event = getPrivateObject(object);
463 EventRecurrenceRulePtr rrule;
464 if (event->getIsDetached()) {
465 LoggerD("This is a detached event.");
466 return JSValueMakeUndefined(context);
468 rrule = event->getRecurrenceRule();
472 return JSValueMakeNull(context);
473 } else if (EventRecurrenceRule::NO_RECURRENCE==rrule->getFrequency()) {
474 return JSValueMakeUndefined(context);
476 return JSCalendarRecurrenceRule::createJSCalendarRecurrenceRule(priv->getContext(), rrule);
481 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
483 return JSValueMakeUndefined(context);
486 bool JSCalendarEvent::setPropertyRecurrenceRule(JSContextRef context,
488 JSStringRef propertyName,
490 JSValueRef* exception)
492 CalendarEventPtr event(NULL);
495 event = getPrivateObject(object);
496 if (event->getIsDetached()) {
497 LoggerW("Can't set the recurrenceRule of a detached event!");
498 DeviceAPI::Common::JSWebAPIErrorFactory::postException(context, exception, DeviceAPI::Common::JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR);
501 if (JSValueIsNull(context, value)) {
502 EventRecurrenceRulePtr rrule(NULL);
503 event->setRecurrenceRule(rrule);
504 } else if (JSValueIsUndefined(context, value)) {
505 EventRecurrenceRulePtr rrule( new EventRecurrenceRule() );
506 event->setRecurrenceRule(rrule);
508 event->setRecurrenceRule(JSCalendarRecurrenceRule::getPrivateObject(JSValueToObject(context, value, NULL)));
514 LoggerW("Exception: "<<_rethrown_exception.GetMessage());