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>
37 #include <SecurityExceptions.h>
38 #include <GlobalContextManager.h>
39 #include <TimeTracer.h>
43 using namespace WrtDeviceApis::Commons;
44 using namespace WrtDeviceApis::CommonsJavaScript;
45 using namespace DeviceAPI::Common;
46 using namespace DeviceAPI::Time;
51 using WrtDeviceApis::Commons::UnknownException;
52 using WrtDeviceApis::Commons::NotFoundException;
54 JSClassDefinition JSCalendarEvent::m_classInfo = {
56 kJSClassAttributeNone,
57 TIZEN_INTERFACE_CALENDAR_EVENT,
58 JSCalendarItemProperties::getClassRef(),
66 NULL, //DeleteProperty,
67 NULL, //GetPropertyNames,
68 NULL, //CallAsFunction,
74 JSStaticValue JSCalendarEvent::m_property[] = {
75 { TIZEN_CALENDAR_EVENT_ID, getPropertyId, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
76 { TIZEN_CALENDAR_EVENT_IS_DETACHED, getPropertyIsDetached, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
77 { TIZEN_CALENDAR_EVENT_AVAILABILITY, getPropertyAvailability, setPropertyAvailability, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
78 { TIZEN_CALENDAR_EVENT_RECURRENCE_RULE, getPropertyRecurrenceRule, setPropertyRecurrenceRule, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
83 JSStaticFunction JSCalendarEvent::m_function[] = {
84 { CALENDAR_FUNCTION_API_EXPAND_RECURRENCE, expandRecurrence, kJSPropertyAttributeNone },
89 JSClassRef JSCalendarEvent::m_jsClassRef = JSClassCreate(JSCalendarEvent::getClassInfo());
91 ICalendarPtr JSCalendarEvent::m_calendar;
93 void JSCalendarEvent::initialize(JSContextRef context,
96 if (!JSObjectGetPrivate(object)) {
97 LoggerD("Create calendar event private object.");
98 CalendarEventPtr event( new CalendarEvent() );
99 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
100 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
104 LoggerD("Private object already set.");
107 if (NULL==m_calendar) {
108 m_calendar = CalendarFactory::getInstance().createCalendarObject();
109 m_calendar->setType(CalendarEvent::EVENT_TYPE);
110 LoggerD("Static calendar for event created.");
114 void JSCalendarEvent::finalize(JSObjectRef object)
116 CalendarEventPrivObject* priv = static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
119 JSObjectSetPrivate(object, NULL);
123 JSObjectRef DLL_EXPORT JSCalendarEvent::constructor(JSContextRef context,
124 JSObjectRef constructor,
125 size_t argumentCount,
126 const JSValueRef arguments[],
127 JSValueRef* exception)
129 CalendarEventPtr event(new CalendarEvent());
130 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
132 DeviceAPI::Common::SecurityAccessor *securityAccessor = NULL;
136 securityAccessor = DeviceAPI::Common::JSObjectGetSecurityAccessor(context, constructor);
138 catch(BasePlatformException &e)
140 event->setCalendarType(CalendarEvent::EVENT_TYPE);
141 return createJSCalendarEvent(globalContext, event, securityAccessor);
146 CalendarConverter converter(globalContext);
148 if (argumentCount==0) {
149 LoggerD("No arguments provided.");
150 } else if (argumentCount==1) {
151 LoggerI("eventInitDict case");
152 if (JSValueIsUndefined(context, arguments[0]) || JSValueIsNull(context, arguments[0])) {
153 LoggerD("Null or undefined case.");
154 } else if (JSValueIsObject(context, arguments[0])) {
155 event = converter.toItem(arguments[0], false);
157 ThrowMsg(ConversionException, "Parameter conversion failed.");
160 //ThrowMsg(ConversionException, "Parameter conversion failed.");
162 } else if (argumentCount>=2) {
163 LoggerI("event stringRepresentation case");
164 std::string eventStr;
165 CalendarEvent::VObjectFormat format = CalendarEvent::UNDEFINED_FORMAT;
166 eventStr = converter.toString(arguments[0]);
167 format = converter.toVObjectFormat(converter.toString(arguments[1]));
169 if (NULL==m_calendar) {
170 m_calendar = CalendarFactory::getInstance().createCalendarObject();
171 m_calendar->setType(CalendarEvent::EVENT_TYPE);
172 LoggerD("Static calendar for event created.");
175 IEventCreateEventFromStringPtr dplEvent(new IEventCreateEventFromString());
176 dplEvent->setEventString(eventStr);
177 dplEvent->setFormat(format);
178 dplEvent->setForSynchronousCall();
179 m_calendar->createEventFromString(dplEvent);
181 // Process the returned object.
182 if (dplEvent->getResult()) {
183 LoggerI("Successfully created an event.");
184 event = dplEvent->getEvent();
186 if (dplEvent->getExceptionCode()==ExceptionCodes::InvalidArgumentException) {
187 //ThrowMsg(InvalidArgumentException, "Wrong string to convert.");
189 //ThrowMsg(UnknownException, "Converting string failed.");
194 event->setCalendarType(CalendarEvent::EVENT_TYPE);
195 return createJSCalendarEvent(globalContext, event, securityAccessor);
197 Catch(UnsupportedException)
199 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
200 //return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
202 Catch(InvalidArgumentException)
204 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
205 //return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
207 Catch(ConversionException)
209 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
210 //return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
214 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
215 //return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
218 event->setCalendarType(CalendarEvent::EVENT_TYPE);
219 return createJSCalendarEvent(globalContext, event, securityAccessor);
222 JSObjectRef JSCalendarEvent::createJSCalendarEvent(JSContextRef context, CalendarEventPtr event, const DeviceAPI::Common::SecurityAccessor *securityAccessor)
224 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
225 priv->copyAceCheckAccessFunction(securityAccessor);
226 return JSObjectMake(context, getClassRef(), priv);
229 const JSClassRef DLL_EXPORT JSCalendarEvent::getClassRef()
232 m_jsClassRef = JSClassCreate(&m_classInfo);
237 const JSClassDefinition* JSCalendarEvent::getClassInfo()
242 CalendarEventPtr JSCalendarEvent::getPrivateObject(JSObjectRef object)
244 CalendarEventPrivObject *priv =
245 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
247 ThrowMsg(NullPointerException, "Private object is null");
249 CalendarEventPtr result = priv->getObject();
251 ThrowMsg(NullPointerException, "Private object is null");
256 void JSCalendarEvent::setPrivateObject(const CalendarEventPtr &event,
258 const JSObjectRef object)
262 CalendarEventPrivObject *priv =
263 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
265 priv = new CalendarEventPrivObject(ctx, event);
266 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
272 LoggerE("Error during replacing event object");
276 JSValueRef JSCalendarEvent::expandRecurrence(JSContextRef context,
278 JSObjectRef thisObject,
279 size_t argumentCount,
280 const JSValueRef arguments[],
281 JSValueRef* exception)
283 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
284 CalendarEventPrivObject *privateObject =
285 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(thisObject));
287 TIZEN_CHECK_ACCESS(context, exception, privateObject, CALENDAR_FUNCTION_API_EXPAND_RECURRENCE);
291 if (!privateObject) {
292 ThrowMsg(ConversionException, "Object is null.");
295 CalendarEventPtr event = privateObject->getObject();
297 ThrowMsg(ConversionException, "Parameter conversion failed.");
300 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
301 CalendarConverter converter(context);
303 std::time_t startDate = 0;
304 std::time_t endDate = INT_MAX; // about 60 years in 4 bytes system.
305 TimeUtilConverter timeConverter(context);
306 if (argumentCount>=1) {
307 if (JSValueIsObjectOfClass(context, arguments[0], JSTZDate::getClassRef())) {
308 startDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[0])/1000);
309 LoggerI("startDate: "<<startDate);
311 ThrowMsg(ConversionException, "Wrong first parameter type.");
314 if (argumentCount>=2) {
315 if (JSValueIsObjectOfClass(context, arguments[1], JSTZDate::getClassRef())) {
316 endDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[1])/1000);
317 LoggerI("endDate: "<<endDate);
319 ThrowMsg(ConversionException, "Wrong second parameter type.");
323 JSValueRef onError = argumentCount > 3 ? converter.toFunctionOrNull(arguments[3]) : NULL;
325 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext, NULL, onError);
327 Validator validator(context);
328 if (validator.isCallback(arguments[2])) {
329 cbm->setOnSuccess(arguments[2]);
331 ThrowMsg(ConversionException, "Wrong third parameter type.");
334 cbm->setObject(thisObject);
336 LoggerD("Proceed the expand event to the platform.");
338 IEventExpandEventRecurrencePtr dplEvent(new IEventExpandEventRecurrence());
339 dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(cbm));
340 dplEvent->setForAsynchronousCall(&CalendarResponseDispatcher::getInstance());
341 dplEvent->setEvent(event);
342 dplEvent->setStartDate(startDate);
343 dplEvent->setEndDate(endDate);
344 dplEvent->copyAceCheckAccessFunction(privateObject);
345 m_calendar->expandEventRecurrence(dplEvent);
347 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
348 return JSValueMakeUndefined(context);
350 Catch(UnsupportedException)
352 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
353 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
355 Catch(InvalidArgumentException)
357 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
358 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
360 Catch(ConversionException)
362 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
363 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
365 Catch (NotFoundException)
367 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
368 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
372 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
373 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
377 JSValueRef JSCalendarEvent::getPropertyId(JSContextRef context,
379 JSStringRef propertyName,
380 JSValueRef* exception)
384 CalendarEventPrivObject *privateObject = static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
385 CalendarEventPtr event = privateObject->getObject();
387 EventIdPtr eventId( new EventId() );
389 if (UNDEFINED_ITEM_ID==event->getId()) {
390 return JSValueMakeNull(context);
392 eventId->setUId(event->getUId());
395 std::stringstream ss;
396 std::time_t rid = event->getRecurrenceId();
398 eventId->setRecurrenceId(ss.str());
399 return JSCalendarEventId::createJSCalendarEventId(context, eventId);
403 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
405 return JSValueMakeUndefined(context);
408 JSValueRef JSCalendarEvent::getPropertyIsDetached(JSContextRef context,
410 JSStringRef propertyName,
411 JSValueRef* exception)
415 CalendarEventPtr event = getPrivateObject(object);
416 Converter converter(context);
417 return converter.toJSValueRef(event->getIsDetached());
421 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
423 return JSValueMakeUndefined(context);
426 JSValueRef JSCalendarEvent::getPropertyAvailability(JSContextRef context,
428 JSStringRef propertyName,
429 JSValueRef* exception)
433 CalendarConverter converter(context);
434 CalendarEventPtr event = getPrivateObject(object);
435 std::string availability = converter.toTizenValue(event->getAvailability());
436 return converter.toJSValueRef(availability);
440 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
442 return JSValueMakeUndefined(context);
445 bool JSCalendarEvent::setPropertyAvailability(JSContextRef context,
447 JSStringRef propertyName,
449 JSValueRef* exception)
451 CalendarEventPtr event(NULL);
454 event = getPrivateObject(object);
455 CalendarConverter converter(context);
456 CalendarEvent::EventAvailability availability = converter.toEventAvailability(converter.toString(value));
457 event->setAvailability(availability);
462 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
468 JSValueRef JSCalendarEvent::getPropertyRecurrenceRule(JSContextRef context,
470 JSStringRef propertyName,
471 JSValueRef* exception)
475 CalendarItemPropertiesPrivObject *priv = static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
477 CalendarEventPtr event = getPrivateObject(object);
478 EventRecurrenceRulePtr rrule;
479 if (event->getIsDetached()) {
480 LoggerD("This is a detached event.");
481 return JSValueMakeUndefined(context);
483 rrule = event->getRecurrenceRule();
487 LogInfo("Null rrule.");
488 return JSValueMakeNull(context);
489 } else if (EventRecurrenceRule::NO_RECURRENCE==rrule->getFrequency()) {
490 return JSValueMakeNull(context);
492 return JSCalendarRecurrenceRule::createJSCalendarRecurrenceRule(priv->getContext(), rrule);
497 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
499 return JSValueMakeUndefined(context);
502 bool JSCalendarEvent::setPropertyRecurrenceRule(JSContextRef context,
504 JSStringRef propertyName,
506 JSValueRef* exception)
508 CalendarEventPtr event(NULL);
511 event = getPrivateObject(object);
512 if (event->getIsDetached()) {
513 LoggerW("Can't set the recurrenceRule of a detached event!");
514 DeviceAPI::Common::JSWebAPIErrorFactory::postException(context, exception, DeviceAPI::Common::JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR);
517 if (JSValueIsNull(context, value)) {
518 event->getRecurrenceRule()->setFrequency(EventRecurrenceRule::NO_RECURRENCE);
519 } else if (!JSValueIsObjectOfClass(context, value, JSCalendarRecurrenceRule::getClassRef())) {
520 ThrowMsg(ConversionException, "Wrong parameter type.");
522 event->setRecurrenceRule(JSCalendarRecurrenceRule::getPrivateObject(JSValueToObject(context, value, NULL)));
528 LoggerW("Exception: "<<_rethrown_exception.GetMessage());