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.
20 #include <dpl/log/log.h>
21 #include <CommonsJavaScript/PrivateObject.h>
22 #include <CommonsJavaScript/Converter.h>
23 #include <CommonsJavaScript/JSUtils.h>
24 #include <CommonsJavaScript/Utils.h>
25 #include <CommonsJavaScript/Validator.h>
26 #include <CommonsJavaScript/JSCallbackManager.h>
28 #include "JSCalendarEvent.h"
29 #include "JSCalendarItemProperties.h"
30 #include "CalendarConverter.h"
31 #include "JSCalendarEventId.h"
32 #include "JSCalendarRecurrenceRule.h"
33 #include "plugin_config.h"
34 #include "CalendarResponseDispatcher.h"
35 #include <TimeUtilConverter.h>
37 #include <JSTizenException.h>
38 #include <JSTizenExceptionFactory.h>
39 #include <SecurityExceptions.h>
41 #include "CalendarAsyncCallbackManager.h"
42 #include <GlobalContextManager.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 },
74 { TIZEN_CALENDAR_EVENT_IS_DETACHED, getPropertyIsDetached, NULL, kJSPropertyAttributeReadOnly },
75 { TIZEN_CALENDAR_EVENT_RECURRENCE_RULE, getPropertyRecurrenceRule, setPropertyRecurrenceRule, kJSPropertyAttributeNone },
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 LogDebug("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 LogDebug("Private object already set.");
105 m_calendar->setType(CalendarEvent::EVENT_TYPE);
106 LogDebug("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 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 LogInfo("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 LogInfo("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 LogInfo("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 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
179 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
181 Catch(InvalidArgumentException)
183 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
184 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
186 Catch(ConversionException)
188 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
189 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
193 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
194 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
200 JSObjectRef JSCalendarEvent::createJSCalendarEvent(JSContextRef context, CalendarEventPtr event)
202 CalendarEventPrivObject *priv = new CalendarEventPrivObject(context, event);
203 return JSObjectMake(context, getClassRef(), priv);
206 const JSClassRef JSCalendarEvent::getClassRef()
209 m_jsClassRef = JSClassCreate(&m_classInfo);
214 const JSClassDefinition* JSCalendarEvent::getClassInfo()
219 CalendarEventPtr JSCalendarEvent::getPrivateObject(JSObjectRef object)
221 CalendarEventPrivObject *priv =
222 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
224 ThrowMsg(NullPointerException, "Private object is null");
226 CalendarEventPtr result = priv->getObject();
228 ThrowMsg(NullPointerException, "Private object is null");
233 void JSCalendarEvent::setPrivateObject(const CalendarEventPtr &event,
235 const JSObjectRef object)
239 CalendarEventPrivObject *priv =
240 static_cast<CalendarEventPrivObject*>(JSObjectGetPrivate(object));
242 priv = new CalendarEventPrivObject(ctx, event);
243 if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
249 LogError("Error during replacing event object");
253 JSValueRef JSCalendarEvent::expandRecurrence(JSContextRef context,
255 JSObjectRef thisObject,
256 size_t argumentCount,
257 const JSValueRef arguments[],
258 JSValueRef* exception)
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 LogInfo("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 LogInfo("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 LogDebug("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);
326 return JSValueMakeUndefined(context);
328 Catch(UnsupportedException)
330 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
331 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
333 Catch(InvalidArgumentException)
335 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
336 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
338 Catch(ConversionException)
340 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
341 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
343 Catch (NotFoundException)
345 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
346 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, _rethrown_exception.GetMessage());
350 LogWarning("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 LogWarning("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 LogWarning("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 LogDebug("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 LogWarning("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 LogWarning("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 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
470 DeviceAPI::Common::JSTizenExceptionFactory::postException(context, exception, DeviceAPI::Common::JSTizenException::TYPE_MISMATCH_ERROR);