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>
43 using namespace WrtDeviceApis::Commons;
44 using namespace WrtDeviceApis::CommonsJavaScript;
45 using namespace DeviceAPI::Common;
46 using namespace DeviceAPI::Time;
51 JSClassDefinition JSCalendarEvent::m_classInfo = {
53 kJSClassAttributeNone,
54 TIZEN_INTERFACE_CALENDAR_EVENT,
55 JSCalendarItemProperties::getClassRef(),
63 NULL, //DeleteProperty,
64 NULL, //GetPropertyNames,
65 NULL, //CallAsFunction,
71 JSStaticValue JSCalendarEvent::m_property[] = {
72 { TIZEN_CALENDAR_EVENT_ID, getPropertyId, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
73 { TIZEN_CALENDAR_EVENT_IS_DETACHED, getPropertyIsDetached, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
74 { TIZEN_CALENDAR_EVENT_RECURRENCE_RULE, getPropertyRecurrenceRule, setPropertyRecurrenceRule, kJSPropertyAttributeNone | kJSPropertyAttributeDontDelete },
79 JSStaticFunction JSCalendarEvent::m_function[] = {
80 { CALENDAR_FUNCTION_API_EXPAND_RECURRENCE, expandRecurrence, kJSPropertyAttributeNone },
85 JSClassRef JSCalendarEvent::m_jsClassRef = JSClassCreate(JSCalendarEvent::getClassInfo());
87 ICalendarPtr JSCalendarEvent::m_calendar = CalendarFactory::getInstance().createCalendarObject();
89 void JSCalendarEvent::initialize(JSContextRef context,
92 if (!JSObjectGetPrivate(object)) {
93 LoggerD("Create calendar event private object.");
94 CalendarEventPtr event( new CalendarEvent() );
95 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
96 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
100 LoggerD("Private object already set.");
104 m_calendar->setType(CalendarEvent::EVENT_TYPE);
105 LoggerD("Calendar object type is set to event.");
109 void JSCalendarEvent::finalize(JSObjectRef object)
111 CalendarEventPrivObject* priv = static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
114 JSObjectSetPrivate(object, NULL);
118 JSObjectRef JSCalendarEvent::constructor(JSContextRef context,
119 JSObjectRef constructor,
120 size_t argumentCount,
121 const JSValueRef arguments[],
122 JSValueRef* exception)
126 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
128 CalendarConverter converter(globalContext);
129 CalendarEventPtr event;
131 if (argumentCount==0) {
132 CalendarEventPtr result(new CalendarEvent());
134 } else if (argumentCount==1) {
135 LoggerI("eventInitDict case");
136 if (JSValueIsUndefined(context, arguments[0]) || JSValueIsNull(context, arguments[0])) {
137 CalendarEventPtr result(new CalendarEvent());
139 } else if (JSValueIsObject(context, arguments[0])) {
140 event = converter.toItem(arguments[0]);
142 ThrowMsg(ConversionException, "Parameter conversion failed.");
145 ThrowMsg(ConversionException, "Parameter conversion failed.");
147 } else if (argumentCount>=2) {
148 LoggerI("event stringRepresentation case");
149 std::string eventStr;
150 CalendarEvent::VObjectFormat format = CalendarEvent::UNDEFINED_FORMAT;
151 eventStr = converter.toString(arguments[0]);
152 format = converter.toVObjectFormat(converter.toString(arguments[1]));
154 IEventCreateEventFromStringPtr dplEvent(new IEventCreateEventFromString());
155 dplEvent->setEventString(eventStr);
156 dplEvent->setFormat(format);
157 dplEvent->setForSynchronousCall();
158 m_calendar->createEventFromString(dplEvent);
160 // Process the returned object.
161 if (dplEvent->getResult()) {
162 LoggerI("Successfully created an event.");
163 event = dplEvent->getEvent();
165 if (dplEvent->getExceptionCode()==ExceptionCodes::InvalidArgumentException) {
166 ThrowMsg(InvalidArgumentException, "Wrong string to convert.");
168 ThrowMsg(UnknownException, "Converting string failed.");
173 return createJSCalendarEvent(globalContext, event);
175 Catch(UnsupportedException)
177 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
178 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
180 Catch(InvalidArgumentException)
182 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
183 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
185 Catch(ConversionException)
187 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
188 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
192 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
193 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
199 JSObjectRef JSCalendarEvent::createJSCalendarEvent(JSContextRef context, CalendarEventPtr event)
201 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
202 return JSObjectMake(context, getClassRef(), priv);
205 const JSClassRef JSCalendarEvent::getClassRef()
208 m_jsClassRef = JSClassCreate(&m_classInfo);
213 const JSClassDefinition* JSCalendarEvent::getClassInfo()
218 CalendarEventPtr JSCalendarEvent::getPrivateObject(JSObjectRef object)
220 CalendarEventPrivObject *priv =
221 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
223 ThrowMsg(NullPointerException, "Private object is null");
225 CalendarEventPtr result = priv->getObject();
227 ThrowMsg(NullPointerException, "Private object is null");
232 void JSCalendarEvent::setPrivateObject(const CalendarEventPtr &event,
234 const JSObjectRef object)
238 CalendarEventPrivObject *priv =
239 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
241 priv = new CalendarEventPrivObject(ctx, event);
242 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
248 LoggerE("Error during replacing event object");
252 JSValueRef JSCalendarEvent::expandRecurrence(JSContextRef context,
254 JSObjectRef thisObject,
255 size_t argumentCount,
256 const JSValueRef arguments[],
257 JSValueRef* exception)
259 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
260 CalendarEventPrivObject *privateObject =
261 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(thisObject));
263 AceSecurityStatus status = CALENDAR_CHECK_ACCESS(CALENDAR_FUNCTION_API_EXPAND_RECURRENCE);
265 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
269 if (!privateObject) {
270 ThrowMsg(ConversionException, "Object is null.");
273 CalendarEventPtr event = privateObject->getObject();
275 ThrowMsg(ConversionException, "Parameter conversion failed.");
278 JSContextRef globalContext = privateObject->getContext();
279 CalendarConverter converter(context);
281 std::time_t startDate = 0;
282 std::time_t endDate = INT_MAX; // about 60 years in 4 bytes system.
283 TimeUtilConverter timeConverter(context);
284 if (argumentCount>=1) {
285 if (JSValueIsObjectOfClass(context, arguments[0], JSTZDate::getClassRef())) {
286 startDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[0])/1000);
287 LoggerI("startDate: "<<startDate);
289 ThrowMsg(ConversionException, "Wrong first parameter type.");
292 if (argumentCount>=2) {
293 if (JSValueIsObjectOfClass(context, arguments[1], JSTZDate::getClassRef())) {
294 endDate = (long long int) (timeConverter.getTimeInMilliseconds(arguments[1])/1000);
295 LoggerI("endDate: "<<endDate);
297 ThrowMsg(ConversionException, "Wrong second parameter type.");
301 JSValueRef onError = argumentCount > 3 ? converter.toFunctionOrNull(arguments[3]) : NULL;
303 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(globalContext, NULL, onError);
305 Validator validator(context);
306 if (validator.isCallback(arguments[2])) {
307 cbm->setOnSuccess(arguments[2]);
309 ThrowMsg(ConversionException, "Wrong third parameter type.");
312 cbm->setObject(thisObject);
314 LoggerD("Proceed the expand event to the platform.");
316 IEventExpandEventRecurrencePtr dplEvent(new IEventExpandEventRecurrence());
317 dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(cbm));
318 dplEvent->setForAsynchronousCall(&CalendarResponseDispatcher::getInstance());
319 dplEvent->setEvent(event);
320 dplEvent->setStartDate(startDate);
321 dplEvent->setEndDate(endDate);
322 m_calendar->expandEventRecurrence(dplEvent);
324 CalendarAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, globalContext);
325 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
326 return JSValueMakeUndefined(context);
328 Catch(UnsupportedException)
330 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
331 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
333 Catch(InvalidArgumentException)
335 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
336 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
338 Catch(ConversionException)
340 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
341 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
343 Catch (NotFoundException)
345 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
346 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
350 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
351 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
355 JSValueRef JSCalendarEvent::getPropertyId(JSContextRef context,
357 JSStringRef propertyName,
358 JSValueRef* exception)
362 CalendarEventPrivObject *privateObject = static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
363 CalendarEventPtr event = privateObject->getObject();
365 EventIdPtr eventId( new EventId() );
367 if (UNDEFINED_ITEM_ID==event->getId()) {
368 return JSValueMakeNull(context);
370 eventId->setUId(event->getUId());
373 std::stringstream ss;
374 std::time_t rid = event->getRecurrenceId();
376 eventId->setRecurrenceId(ss.str());
377 return JSCalendarEventId::createJSCalendarEventId(context, eventId);
381 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
383 return JSValueMakeUndefined(context);
386 JSValueRef JSCalendarEvent::getPropertyIsDetached(JSContextRef context,
388 JSStringRef propertyName,
389 JSValueRef* exception)
393 CalendarEventPtr event = getPrivateObject(object);
394 if(CalendarEvent::EVENT_TYPE != event->getCalendarType()) {
395 return JSValueMakeUndefined(context);
398 Converter converter(context);
399 return converter.toJSValueRef(event->getIsDetached());
403 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
405 return JSValueMakeUndefined(context);
408 JSValueRef JSCalendarEvent::getPropertyRecurrenceRule(JSContextRef context,
410 JSStringRef propertyName,
411 JSValueRef* exception)
415 CalendarItemPropertiesPrivObject *priv = static_cast<CalendarItemPropertiesPrivObject*>(JSObjectGetPrivate(object));
417 CalendarEventPtr event = getPrivateObject(object);
418 EventRecurrenceRulePtr rrule;
419 if (event->getIsDetached()) {
420 LoggerD("This is a detached event.");
421 return JSValueMakeUndefined(context);
423 rrule = event->getRecurrenceRule();
427 return JSValueMakeNull(context);
428 } else if (EventRecurrenceRule::NO_RECURRENCE==rrule->getFrequency()) {
429 return JSValueMakeUndefined(context);
431 return JSCalendarRecurrenceRule::createJSCalendarRecurrenceRule(priv->getContext(), rrule);
436 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
438 return JSValueMakeUndefined(context);
441 bool JSCalendarEvent::setPropertyRecurrenceRule(JSContextRef context,
443 JSStringRef propertyName,
445 JSValueRef* exception)
447 CalendarEventPtr event(NULL);
450 event = getPrivateObject(object);
451 if (event->getIsDetached()) {
452 LoggerW("Can't set the recurrenceRule of a detached event!");
453 DeviceAPI::Common::JSTizenExceptionFactory::postException(context, exception, DeviceAPI::Common::JSTizenException::NOT_SUPPORTED_ERROR);
456 if (JSValueIsNull(context, value)) {
457 EventRecurrenceRulePtr rrule(NULL);
458 event->setRecurrenceRule(rrule);
459 } else if (JSValueIsUndefined(context, value)) {
460 EventRecurrenceRulePtr rrule( new EventRecurrenceRule() );
461 event->setRecurrenceRule(rrule);
463 event->setRecurrenceRule(JSCalendarRecurrenceRule::getPrivateObject(JSValueToObject(context, value, NULL)));
469 LoggerW("Exception: "<<_rethrown_exception.GetMessage());