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 <JSTizenException.h>
36 #include <JSTizenExceptionFactory.h>
37 #include <SecurityExceptions.h>
38 #include "CalendarAsyncCallbackManager.h"
39 #include <GlobalContextManager.h>
40 #include <TimeTracer.h>
44 using namespace WrtDeviceApis::Commons;
45 using namespace WrtDeviceApis::CommonsJavaScript;
46 using namespace DeviceAPI::Common;
47 using namespace DeviceAPI::Time;
52 JSClassDefinition JSCalendarEvent::m_classInfo = {
54 kJSClassAttributeNone,
55 TIZEN_INTERFACE_CALENDAR_EVENT,
56 JSCalendarItemProperties::getClassRef(),
64 NULL, //DeleteProperty,
65 NULL, //GetPropertyNames,
66 NULL, //CallAsFunction,
72 JSStaticValue JSCalendarEvent::m_property[] = {
73 { TIZEN_CALENDAR_EVENT_ID, getPropertyId, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
74 { TIZEN_CALENDAR_EVENT_IS_DETACHED, getPropertyIsDetached, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
75 { TIZEN_CALENDAR_EVENT_RECURRENCE_RULE, getPropertyRecurrenceRule, setPropertyRecurrenceRule, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
80 JSStaticFunction JSCalendarEvent::m_function[] = {
81 { CALENDAR_FUNCTION_API_EXPAND_RECURRENCE, expandRecurrence, kJSPropertyAttributeNone },
86 JSClassRef JSCalendarEvent::m_jsClassRef = JSClassCreate(JSCalendarEvent::getClassInfo());
88 ICalendarPtr JSCalendarEvent::m_calendar = CalendarFactory::getInstance().createCalendarObject();
90 void JSCalendarEvent::initialize(JSContextRef context,
93 if (!JSObjectGetPrivate(object)) {
94 LoggerD("Create calendar event private object.");
95 CalendarEventPtr event( new CalendarEvent() );
96 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
97 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
101 LoggerD("Private object already set.");
105 m_calendar->setType(CalendarEvent::EVENT_TYPE);
106 LoggerD("Calendar object type is set to event.");
110 void JSCalendarEvent::finalize(JSObjectRef object)
112 CalendarEventPrivObject* priv = static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
115 JSObjectSetPrivate(object, NULL);
119 JSObjectRef DLL_EXPORT JSCalendarEvent::constructor(JSContextRef context,
120 JSObjectRef constructor,
121 size_t argumentCount,
122 const JSValueRef arguments[],
123 JSValueRef* exception)
127 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
129 CalendarConverter converter(globalContext);
130 CalendarEventPtr event;
132 if (argumentCount==0) {
133 CalendarEventPtr result(new CalendarEvent());
135 } else if (argumentCount==1) {
136 LoggerI("eventInitDict case");
137 if (JSValueIsUndefined(context, arguments[0]) || JSValueIsNull(context, arguments[0])) {
138 CalendarEventPtr result(new CalendarEvent());
140 } else if (JSValueIsObject(context, arguments[0])) {
141 event = converter.toItem(arguments[0]);
143 ThrowMsg(ConversionException, "Parameter conversion failed.");
146 ThrowMsg(ConversionException, "Parameter conversion failed.");
148 } else if (argumentCount>=2) {
149 LoggerI("event stringRepresentation case");
150 std::string eventStr;
151 CalendarEvent::VObjectFormat format = CalendarEvent::UNDEFINED_FORMAT;
152 eventStr = converter.toString(arguments[0]);
153 format = converter.toVObjectFormat(converter.toString(arguments[1]));
155 IEventCreateEventFromStringPtr dplEvent(new IEventCreateEventFromString());
156 dplEvent->setEventString(eventStr);
157 dplEvent->setFormat(format);
158 dplEvent->setForSynchronousCall();
159 m_calendar->createEventFromString(dplEvent);
161 // Process the returned object.
162 if (dplEvent->getResult()) {
163 LoggerI("Successfully created an event.");
164 event = dplEvent->getEvent();
166 if (dplEvent->getExceptionCode()==ExceptionCodes::InvalidArgumentException) {
167 ThrowMsg(InvalidArgumentException, "Wrong string to convert.");
169 ThrowMsg(UnknownException, "Converting string failed.");
174 return createJSCalendarEvent(globalContext, event);
176 Catch(UnsupportedException)
178 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
179 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
183 Catch(InvalidArgumentException)
185 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
186 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
190 Catch(ConversionException)
192 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
193 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
199 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
200 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
206 JSObjectRef JSCalendarEvent::createJSCalendarEvent(JSContextRef context, CalendarEventPtr event)
208 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
209 return JSObjectMake(context, getClassRef(), priv);
212 const JSClassRef DLL_EXPORT JSCalendarEvent::getClassRef()
215 m_jsClassRef = JSClassCreate(&m_classInfo);
220 const JSClassDefinition* JSCalendarEvent::getClassInfo()
225 CalendarEventPtr JSCalendarEvent::getPrivateObject(JSObjectRef object)
227 CalendarEventPrivObject *priv =
228 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
230 ThrowMsg(NullPointerException, "Private object is null");
232 CalendarEventPtr result = priv->getObject();
234 ThrowMsg(NullPointerException, "Private object is null");
239 void JSCalendarEvent::setPrivateObject(const CalendarEventPtr &event,
241 const JSObjectRef object)
245 CalendarEventPrivObject *priv =
246 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
248 priv = new CalendarEventPrivObject(ctx, event);
249 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
255 LoggerE("Error during replacing event object");
259 JSValueRef JSCalendarEvent::expandRecurrence(JSContextRef context,
261 JSObjectRef thisObject,
262 size_t argumentCount,
263 const JSValueRef arguments[],
264 JSValueRef* exception)
266 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
267 CalendarEventPrivObject *privateObject =
268 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(thisObject));
270 AceSecurityStatus status = CALENDAR_CHECK_ACCESS(CALENDAR_FUNCTION_API_EXPAND_RECURRENCE);
272 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
276 if (!privateObject) {
277 ThrowMsg(ConversionException, "Object is null.");
280 CalendarEventPtr event = privateObject->getObject();
282 ThrowMsg(ConversionException, "Parameter conversion failed.");
285 JSContextRef globalContext = privateObject->getContext();
286 CalendarConverter converter(context);
288 std::time_t startDate = 0;
289 std::time_t endDate = INT_MAX; // about 60 years in 4 bytes system.
290 TimeUtilConverter timeConverter(context);
291 if (argumentCount>=1) {
292 if (JSValueIsObjectOfClass(context, arguments[0], JSTZDate::getClassRef())) {
293 startDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[0])/1000);
294 LoggerI("startDate: "<<startDate);
296 ThrowMsg(ConversionException, "Wrong first parameter type.");
299 if (argumentCount>=2) {
300 if (JSValueIsObjectOfClass(context, arguments[1], JSTZDate::getClassRef())) {
301 endDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[1])/1000);
302 LoggerI("endDate: "<<endDate);
304 ThrowMsg(ConversionException, "Wrong second parameter type.");
308 JSValueRef onError = argumentCount > 3 ? converter.toFunctionOrNull(arguments[3]) : NULL;
310 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext, NULL, onError);
312 Validator validator(context);
313 if (validator.isCallback(arguments[2])) {
314 cbm->setOnSuccess(arguments[2]);
316 ThrowMsg(ConversionException, "Wrong third parameter type.");
319 cbm->setObject(thisObject);
321 LoggerD("Proceed the expand event to the platform.");
323 IEventExpandEventRecurrencePtr dplEvent(new IEventExpandEventRecurrence());
324 dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(cbm));
325 dplEvent->setForAsynchronousCall(&CalendarResponseDispatcher::getInstance());
326 dplEvent->setEvent(event);
327 dplEvent->setStartDate(startDate);
328 dplEvent->setEndDate(endDate);
329 m_calendar->expandEventRecurrence(dplEvent);
331 CalendarAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, globalContext);
332 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
333 return JSValueMakeUndefined(context);
335 Catch(UnsupportedException)
337 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
338 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
340 Catch(InvalidArgumentException)
342 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
343 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
345 Catch(ConversionException)
347 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
348 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
350 Catch (NotFoundException)
352 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
353 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
357 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
358 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::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 if(CalendarEvent::EVENT_TYPE != event->getCalendarType()) {
402 return JSValueMakeUndefined(context);
405 Converter converter(context);
406 return converter.toJSValueRef(event->getIsDetached());
410 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
412 return JSValueMakeUndefined(context);
415 JSValueRef JSCalendarEvent::getPropertyRecurrenceRule(JSContextRef context,
417 JSStringRef propertyName,
418 JSValueRef* exception)
422 CalendarItemPropertiesPrivObject *priv = static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
424 CalendarEventPtr event = getPrivateObject(object);
425 EventRecurrenceRulePtr rrule;
426 if (event->getIsDetached()) {
427 LoggerD("This is a detached event.");
428 return JSValueMakeUndefined(context);
430 rrule = event->getRecurrenceRule();
434 return JSValueMakeNull(context);
435 } else if (EventRecurrenceRule::NO_RECURRENCE==rrule->getFrequency()) {
436 return JSValueMakeUndefined(context);
438 return JSCalendarRecurrenceRule::createJSCalendarRecurrenceRule(priv->getContext(), rrule);
443 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
445 return JSValueMakeUndefined(context);
448 bool JSCalendarEvent::setPropertyRecurrenceRule(JSContextRef context,
450 JSStringRef propertyName,
452 JSValueRef* exception)
454 CalendarEventPtr event(NULL);
457 event = getPrivateObject(object);
458 if (event->getIsDetached()) {
459 LoggerW("Can't set the recurrenceRule of a detached event!");
460 DeviceAPI::Common::JSTizenExceptionFactory::postException(context, exception, DeviceAPI::Common::JSTizenException::NOT_SUPPORTED_ERROR);
463 if (JSValueIsNull(context, value)) {
464 EventRecurrenceRulePtr rrule(NULL);
465 event->setRecurrenceRule(rrule);
466 } else if (JSValueIsUndefined(context, value)) {
467 EventRecurrenceRulePtr rrule( new EventRecurrenceRule() );
468 event->setRecurrenceRule(rrule);
470 event->setRecurrenceRule(JSCalendarRecurrenceRule::getPrivateObject(JSValueToObject(context, value, NULL)));
476 LoggerW("Exception: "<<_rethrown_exception.GetMessage());