Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Calendar / JSCalendarRecurrenceRule.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include "JSCalendarRecurrenceRule.h"
19 #include <dpl/log/log.h>
20 #include <Tizen/Common/JSTizenException.h>
21 #include <Tizen/Common/JSTizenExceptionFactory.h>
22 #include <CommonsJavaScript/Converter.h>
23 #include "CalendarConverter.h"
24 #include <Tizen/TimeUtil/TimeUtilConverter.h>
25 #include <Tizen/TimeUtil/JSTZDate.h>
26
27 using namespace TizenApis::Api::Calendar;
28 using namespace WrtDeviceApis::Commons;
29 using namespace WrtDeviceApis::CommonsJavaScript;
30 using namespace TizenApis::Commons;
31
32 namespace TizenApis {
33 namespace Tizen1_0 {
34 namespace Calendar {
35
36 JSClassDefinition JSCalendarRecurrenceRule::m_classInfo = {
37     0,
38     kJSClassAttributeNone,
39     TIZEN_INTERFACE_CALENDAR_RECURRENCE_RULE,
40     0,
41     m_property,
42     NULL, //m_function,
43     initialize,
44     finalize,
45     NULL, //hasProperty,
46     NULL, //getProperty,
47     NULL, //setProperty,
48     NULL, //deleteProperty,
49     NULL, //getPropertyNames,
50     NULL, //callAsFunction,
51     constructor,
52     NULL, //hasInstance,
53     NULL, //convertToType,
54 };
55
56 JSStaticValue JSCalendarRecurrenceRule::m_property[] = {
57     { TIZEN_RECURRENCE_RULE_FREQUENCY, getProperty, setProperty, kJSPropertyAttributeNone },
58     { TIZEN_RECURRENCE_RULE_INTERVAL, getProperty, setProperty, kJSPropertyAttributeNone },
59     { TIZEN_RECURRENCE_RULE_UNTIL_DATE, getProperty, setProperty, kJSPropertyAttributeNone },
60     { TIZEN_RECURRENCE_RULE_OCCURRENCE_COUNT, getProperty, setProperty, kJSPropertyAttributeNone },
61 //    { TIZEN_RECURRENCE_RULE_DAYS_OF_THE_MONTH, getProperty, setProperty, kJSPropertyAttributeNone },
62     { TIZEN_RECURRENCE_RULE_DAYS_OF_THE_WEEK, getProperty, setProperty, kJSPropertyAttributeNone },
63 //    { TIZEN_RECURRENCE_RULE_DAYS_OF_THE_YEAR, getProperty, setProperty, kJSPropertyAttributeNone },
64 //    { TIZEN_RECURRENCE_RULE_WEEKS_OF_THE_YEAR, getProperty, setProperty, kJSPropertyAttributeNone },
65     { TIZEN_RECURRENCE_RULE_SET_POSITION, getProperty, setProperty, kJSPropertyAttributeNone },
66     { TIZEN_RECURRENCE_RULE_EXCEPTIONS, getProperty, setProperty, kJSPropertyAttributeNone },
67
68     { 0, 0, 0, 0 }
69 };
70
71 JSClassRef JSCalendarRecurrenceRule::m_jsClassRef = JSClassCreate(
72         JSCalendarRecurrenceRule::getClassInfo());
73
74 const JSClassDefinition* JSCalendarRecurrenceRule::getClassInfo()
75 {
76     return &(m_classInfo);
77 }
78
79 JSClassRef JSCalendarRecurrenceRule::getClassRef()
80 {
81     if (!m_jsClassRef) {
82         m_jsClassRef = JSClassCreate(&m_classInfo);
83     }
84     return m_jsClassRef;
85 }
86
87 JSObjectRef JSCalendarRecurrenceRule::createJSCalendarRecurrenceRule(JSContextRef context, EventRecurrenceRulePtr rule)
88 {
89     RecurrenceRulePrivateObject *priv = new RecurrenceRulePrivateObject(context, rule);
90     return JSObjectMake(context, getClassRef(), priv);
91 }
92
93 void JSCalendarRecurrenceRule::initialize(JSContextRef context, JSObjectRef object)
94 {
95     LogDebug("enter");
96 }
97
98 void JSCalendarRecurrenceRule::finalize(JSObjectRef object)
99 {
100     LogDebug("enter");
101     RecurrenceRulePrivateObject* priv =
102         static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
103     delete priv;
104     JSObjectSetPrivate(object, NULL);
105 }
106
107 EventRecurrenceRulePtr JSCalendarRecurrenceRule::getPrivateObject(JSObjectRef object)
108 {
109     LogDebug("entered");
110     RecurrenceRulePrivateObject *priv =
111         static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
112     if (!priv) {
113         ThrowMsg(NullPointerException, "Private object is null.");
114     }
115     EventRecurrenceRulePtr result = priv->getObject();
116     if (!result) {
117         ThrowMsg(NullPointerException, "Private object is null.");
118     }
119     return result;
120 }
121
122 void JSCalendarRecurrenceRule::setPrivateObject(const EventRecurrenceRulePtr &rrule,
123         JSContextRef ctx,
124         const JSObjectRef object)
125 {
126     LogDebug("entered");
127     Try
128     {
129         RecurrenceRulePrivateObject *priv =
130             static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
131         delete priv;
132         priv = new RecurrenceRulePrivateObject(ctx, rrule);
133         if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
134             delete priv;
135         }
136     }
137     Catch(Exception)
138     {
139         LogError("Error during replacing rrule object.");
140     }
141 }
142
143 JSObjectRef JSCalendarRecurrenceRule::constructor(JSContextRef context,
144     JSObjectRef constructor,
145     size_t argumentCount,
146     const JSValueRef arguments[],
147     JSValueRef* exception)
148 {
149     LogDebug("entered");
150
151     Try
152     {
153         RecurrenceRulePrivateObject* privateObject = static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(constructor));
154         JSContextRef globalContext = privateObject ? privateObject->getContext() : context;
155
156         CalendarConverter converter(globalContext);
157         EventRecurrenceRulePtr rrule;
158
159         if (argumentCount==1) {
160             if (!JSValueIsString(context, arguments[0])) {
161                 ThrowMsg(ConversionException, "Wrong parameter type.");
162             }
163
164             EventRecurrenceRulePtr result( new EventRecurrenceRule());
165             rrule = result;
166             rrule->setFrequency(converter.toRecurrenceFrequency(converter.toString(arguments[0])));
167             if (!rrule) {
168                 ThrowMsg(ConversionException, "Parameter conversion failed.");
169             }
170         } else if (argumentCount==2) {
171             if (!JSValueIsString(context, arguments[0])) {
172                 ThrowMsg(ConversionException, "Wrong parameter type.");
173             }
174
175             rrule = converter.toEventRecurrenceRule(arguments[1]);
176             if (!rrule) {
177                 ThrowMsg(ConversionException, "Parameter conversion failed.");
178             }
179             rrule->setFrequency(converter.toRecurrenceFrequency(converter.toString(arguments[0])));
180         } else {
181             ThrowMsg(InvalidArgumentException, "Wrong number of parameters.");
182         }
183
184         return createJSCalendarRecurrenceRule(globalContext, rrule);
185     }
186     Catch(UnsupportedException)
187     {
188         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
189         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
190     }
191     Catch(InvalidArgumentException)
192     {
193         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
194         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
195     }
196     Catch(ConversionException)
197     {
198         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
199         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
200     }
201     Catch(Exception)
202     {
203         LogWarning("Exception: "<<_rethrown_exception.GetMessage());
204         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
205     }
206
207     return NULL;
208 }
209
210 JSValueRef JSCalendarRecurrenceRule::getProperty(JSContextRef context,
211         JSObjectRef object,
212         JSStringRef propertyName,
213         JSValueRef* exception)
214 {
215     LogDebug("enter");
216     CalendarConverterFactory::ConverterType converter =
217         CalendarConverterFactory::getConverter(context);
218     Try
219     {
220         RecurrenceRulePrivateObject* priv =
221             static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
222         if (!priv) {
223             Throw(NullPointerException);
224         }
225         EventRecurrenceRulePtr rrule = priv->getObject();
226
227         if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_FREQUENCY)) {
228             return converter->toJSValueRef(converter->toTizenValue(rrule->getFrequency()));
229         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_INTERVAL)) {
230             return converter->toJSValueRef(rrule->getInterval());
231         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_UNTIL_DATE)) {
232             if (!rrule) {
233                 Throw(NullPointerException);
234             }
235             if (rrule->getEndDate() != 0) {
236                 // Use the global context saved in the event struct.
237                 return JSTZDate::createJSObject(priv->getContext(), rrule->getEndDate(), rrule->getTimeZone());
238             } else {
239                 return JSValueMakeUndefined(context);
240             }
241         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_OCCURRENCE_COUNT)) {
242             return converter->toJSValueRefLong(rrule->getOccurrenceCount());
243 //        } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_MONTH)) {
244 //            return converter->toJSValueRef(rrule->getDaysOfTheMonth());
245         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_WEEK)) {
246            return converter->toJSValueRef(rrule->getDaysOfTheWeek());
247 //        } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_YEAR)) {
248 //            return converter->toJSValueRef(rrule->getDaysOfTheYear());
249 //        } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_WEEKS_OF_THE_YEAR)) {
250 //            return converter->toJSValueRef(rrule->getWeeksOfTheYear());
251         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_SET_POSITION)) {
252             return converter->toJSValueRef(rrule->getSetPosition());
253         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_EXCEPTIONS)) {
254             JSObjectRef jsResult = JSCreateArrayObject(context, 0, NULL);
255             if (NULL == jsResult) {
256                 LogError("Could not create js array object.");
257                 ThrowMsg(NullPointerException, "Could not create js array object");
258             }
259
260             for (std::size_t i = 0; i < rrule->getExceptions().size(); ++i) {
261                 JSValueRef tmpVal = JSTZDate::createJSObject(priv->getContext(), rrule->getExceptions().at(i), rrule->getTimeZone());
262                 if (!JSSetArrayElement(context, jsResult, i, tmpVal)) {
263                     LogError("Could not insert value into js array.");
264                     ThrowMsg(UnknownException, "Could not insert value into js array");
265                 }
266             }
267
268             return jsResult;
269         }
270     }
271     Catch(Exception)
272     {
273         LogError("invalid property");
274     }
275     return JSValueMakeUndefined(context);
276 }
277
278 bool JSCalendarRecurrenceRule::setProperty(JSContextRef context,
279         JSObjectRef object,
280         JSStringRef propertyName,
281         JSValueRef value,
282         JSValueRef* exception)
283 {
284     LogDebug("entered");
285     CalendarConverterFactory::ConverterType converter =
286         CalendarConverterFactory::getConverter(context);
287     Try
288     {
289         RecurrenceRulePrivateObject* priv =
290             static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
291         if (!priv) {
292             Throw(NullPointerException);
293         }
294         EventRecurrenceRulePtr rrule = priv->getObject();
295
296         if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_FREQUENCY)) {
297             if (!JSValueIsString(context, value)) {
298                 Throw(InvalidArgumentException);
299             }
300             std::string frequency = converter->toString(value);
301             rrule->setFrequency(converter->toRecurrenceFrequency(frequency));
302             return true;
303         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_INTERVAL)) {
304             if (!JSValueIsNumber(context, value)) {
305                 Throw(InvalidArgumentException);
306             }
307             int interval = converter->toInt(value);
308             rrule->setInterval(interval);
309             return true;
310         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_UNTIL_DATE)) {
311             if (!JSValueIsObjectOfClass(context, value, JSTZDate::getClassRef())) {
312                 Throw(InvalidArgumentException);
313             }
314             TimeUtilConverter timeConverter(context);
315             std::time_t untilDate = timeConverter.toTZDateTimeT(value);
316             rrule->setEndDate(untilDate);
317
318             if( rrule->getTimeZone().empty() ) {
319                 std::string timeZone = timeConverter.getPropertiesInTZDate(value).timezone;
320                 rrule->setTimeZone(timeZone);
321             }
322             return true;
323         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_OCCURRENCE_COUNT)) {
324             if (!JSValueIsNumber(context, value)) {
325                 Throw(InvalidArgumentException);
326             }
327             long occurrenceCount = converter->toLong(value);
328             rrule->setOccurrenceCount(occurrenceCount);
329             return true;
330         /*} else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_MONTH)) {
331             std::vector<int> daysOfTheMonth = converter->toVectorOfInts(value);
332             rrule->setDaysOfTheMonth(daysOfTheMonth);
333             return true;*/
334         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_WEEK)) {
335             std::vector<std::string> daysOfTheWeek = converter->toVectorOfStrings(value);
336             rrule->setDaysOfTheWeek(daysOfTheWeek);
337             return true;
338         /*} else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_YEAR)) {
339             std::vector<int> daysOfTheYear = converter->toVectorOfInts(value);
340             rrule->setDaysOfTheYear(daysOfTheYear);
341             return true;
342         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_WEEKS_OF_THE_YEAR)) {
343             std::vector<int> weekOfTheYear = converter->toVectorOfInts(value);
344             rrule->setWeeksOfTheYear(weekOfTheYear);
345             return true;*/
346         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_SET_POSITION)) {
347             return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR);
348             /*
349             bool setPosition = converter->toBool(value);
350             rrule->setSetPosition(setPosition);*/
351             return true;
352         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_EXCEPTIONS)) {
353             // Only save the converted time info.
354             rrule->setExceptions(converter->toVectorOfTimeTFromTZDate(value));
355             return true;
356         }
357     }
358     Catch(Exception)
359     {
360         LogWarning("trying to set incorrect value");
361     }
362     JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR);
363     return false;
364 }
365
366 }
367 }
368 }