wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / Calendar / JSCalendarRecurrenceRule.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 #include "JSCalendarRecurrenceRule.h"
19 #include <JSTizenException.h>
20 #include <JSTizenExceptionFactory.h>
21 #include <CommonsJavaScript/Converter.h>
22 #include "CalendarConverter.h"
23 #include <TimeUtilConverter.h>
24 #include <JSTZDate.h>
25 #include <GlobalContextManager.h>
26 #include <Logger.h>
27
28 using namespace WrtDeviceApis::Commons;
29 using namespace WrtDeviceApis::CommonsJavaScript;
30 using namespace DeviceAPI::Common;
31 using namespace DeviceAPI::Time;
32
33 namespace DeviceAPI {
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_POSITIONS, 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     if (!JSObjectGetPrivate(object)) {
96         LoggerD("Create calendar rrule private object.");
97         EventRecurrenceRulePtr rrule( new EventRecurrenceRule() );
98         RecurrenceRulePrivateObject *priv = new RecurrenceRulePrivateObject(context, rrule);
99         if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
100             delete priv;
101         }
102     } else {
103         LoggerD("Private object already set.");
104     }
105 }
106
107 void JSCalendarRecurrenceRule::finalize(JSObjectRef object)
108 {
109     RecurrenceRulePrivateObject* priv = static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
110     if (priv) {
111         delete priv;
112         JSObjectSetPrivate(object, NULL);
113     }
114 }
115
116 EventRecurrenceRulePtr JSCalendarRecurrenceRule::getPrivateObject(JSObjectRef object)
117 {
118     RecurrenceRulePrivateObject *priv =
119         static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
120     if (!priv) {
121         ThrowMsg(NullPointerException, "Private object is null.");
122     }
123     EventRecurrenceRulePtr result = priv->getObject();
124     if (!result) {
125         ThrowMsg(NullPointerException, "Private object is null.");
126     }
127     return result;
128 }
129
130 void JSCalendarRecurrenceRule::setPrivateObject(const EventRecurrenceRulePtr &rrule,
131         JSContextRef ctx,
132         const JSObjectRef object)
133 {
134     Try
135     {
136         RecurrenceRulePrivateObject *priv =
137             static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
138         delete priv;
139         priv = new RecurrenceRulePrivateObject(ctx, rrule);
140         if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
141             delete priv;
142         }
143     }
144     Catch(Exception)
145     {
146         LoggerE("Error during replacing rrule object.");
147     }
148 }
149
150 JSObjectRef JSCalendarRecurrenceRule::constructor(JSContextRef context,
151     JSObjectRef constructor,
152     size_t argumentCount,
153     const JSValueRef arguments[],
154     JSValueRef* exception)
155 {
156     Try
157     {
158                 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
159         CalendarConverter converter(globalContext);
160         EventRecurrenceRulePtr rrule;
161
162         if (argumentCount==0) {
163             EventRecurrenceRulePtr result( new EventRecurrenceRule());
164             rrule = result;
165         } else if (argumentCount==1) {
166             EventRecurrenceRulePtr result( new EventRecurrenceRule());
167             rrule = result;
168             rrule->setFrequency(converter.toRecurrenceFrequency(converter.toString(arguments[0])));
169         } else if (argumentCount>=2) {
170             if (JSValueIsNull(context, arguments[1]) || JSValueIsUndefined(context, arguments[1])) {
171                 EventRecurrenceRulePtr result( new EventRecurrenceRule());
172                 rrule = result;
173             } else {
174                 if (!JSValueIsObject(context, arguments[1])) {
175                     ThrowMsg(ConversionException, "Wrong second parameter type.");
176                 }
177
178                 rrule = converter.toEventRecurrenceRule(arguments[1]);
179                 if (!rrule) {
180                     ThrowMsg(ConversionException, "Parameter conversion failed.");
181                 }
182             }
183             rrule->setFrequency(converter.toRecurrenceFrequency(converter.toString(arguments[0])));
184         }
185
186         return createJSCalendarRecurrenceRule(context, rrule);
187     }
188     Catch(UnsupportedException)
189     {
190         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
191         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::NOT_SUPPORTED_ERROR, _rethrown_exception.GetMessage());
192     }
193     Catch(InvalidArgumentException)
194     {
195         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
196         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage());
197     }
198     Catch(ConversionException)
199     {
200         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
201         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
202     }
203     Catch(Exception)
204     {
205         LoggerW("Exception: "<<_rethrown_exception.GetMessage());
206         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, _rethrown_exception.GetMessage());
207     }
208
209     return NULL;
210 }
211
212 JSValueRef JSCalendarRecurrenceRule::getProperty(JSContextRef context,
213         JSObjectRef object,
214         JSStringRef propertyName,
215         JSValueRef* exception)
216 {
217     Try
218     {
219         EventRecurrenceRulePtr rrule = getPrivateObject(object);
220                 JSContextRef globalContext = GlobalContextManager::getInstance()->getGlobalContext(context);
221
222             CalendarConverter converter(globalContext);
223             TimeUtilConverter timeConverter(globalContext);
224
225         if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_FREQUENCY)) {
226             return converter.toJSValueRef(converter.toTizenValue(rrule->getFrequency()));
227         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_INTERVAL)) {
228             return converter.toJSValueRef(rrule->getInterval());
229         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_UNTIL_DATE)) {
230             if (UNDEFINED_TIME==rrule->getEndDate()) {
231                 return JSValueMakeNull(context);
232             } else {
233                 return timeConverter.toJSValueRefTZDate((double)(rrule->getEndDate()*1000.0), rrule->getTimeZone());
234             }
235         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_OCCURRENCE_COUNT)) {
236                 if(0<rrule->getOccurrenceCount()) {
237                     return converter.toJSValueRefLong(rrule->getOccurrenceCount());
238                 } else {
239                                 return converter.toJSValueRefLong(-1);
240                         }
241         //} else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_MONTH)) {
242             //return converter.toJSValueRef(rrule->getDaysOfTheMonth());
243         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_WEEK)) {
244                         if(rrule->getDaysOfTheWeekJSRef()) {
245                                 return rrule->getDaysOfTheWeekJSRef();
246                         } else {
247                                 LoggerD("Create a JS object for daysOfTheWeek.");
248                         StringArrayPtr daysOfTheWeek = rrule->getDaysOfTheWeek();
249                                 JSValueRef jsDaysOfTheWeek = converter.toJSValueRefStringArray(daysOfTheWeek);
250                                 rrule->setDaysOfTheWeekJSRef(converter.toJSObjectRef(jsDaysOfTheWeek));
251
252                                 JSValueProtect(globalContext, jsDaysOfTheWeek);
253                                 rrule->setContext(globalContext);
254                     return jsDaysOfTheWeek;
255                         }
256         //} else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_YEAR)) {
257             //return converter.toJSValueRef(rrule->getDaysOfTheYear());
258         //} else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_WEEKS_OF_THE_YEAR)) {
259             //return converter.toJSValueRef(rrule->getWeeksOfTheYear());
260         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_SET_POSITIONS)) {
261                         if(rrule->getSetPositionsJSRef()) {
262                                 return rrule->getSetPositionsJSRef();
263                         } else {
264                                 LoggerD("Create a JS object for setPositions.");
265                                 NumberArrayPtr setPositions = rrule->getSetPositions();
266                                 JSValueRef jsSetPositions = converter.toJSValueRefNumberArray(setPositions);
267                                 rrule->setSetPositionsJSRef(converter.toJSObjectRef(jsSetPositions));
268
269                                 JSValueProtect(globalContext, jsSetPositions);
270                                 rrule->setContext(globalContext);
271                                 return jsSetPositions;
272                         }
273         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_EXCEPTIONS)) {
274                         if(rrule->getExceptionsJSRef()) {
275                                 return rrule->getExceptionsJSRef();
276                         } else {
277                                 LoggerD("Create a JS object for exceptions with time zone: "<<rrule->getTimeZone());
278                                 NumberArrayPtr exceptions = rrule->getExceptions();
279                                 JSValueRef jsExceptions = converter.toJSValueRefTZDateArray(exceptions, rrule->getTimeZone());
280                                 rrule->setExceptionsJSRef(converter.toJSObjectRef(jsExceptions));
281
282                                 JSValueProtect(globalContext, jsExceptions);
283                                 rrule->setContext(globalContext);
284                                 return jsExceptions;
285                         }
286         }
287     }
288     Catch(Exception)
289     {
290                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
291     }
292     return JSValueMakeUndefined(context);
293 }
294
295 bool JSCalendarRecurrenceRule::setProperty(JSContextRef context,
296         JSObjectRef object,
297         JSStringRef propertyName,
298         JSValueRef value,
299         JSValueRef* exception)
300 {
301     CalendarConverter converter(context);
302     Try
303     {
304         RecurrenceRulePrivateObject* priv =
305             static_cast<RecurrenceRulePrivateObject*>(JSObjectGetPrivate(object));
306         if (!priv) {
307             ThrowMsg(NullPointerException, "Private object is NULL.");
308         }
309         EventRecurrenceRulePtr rrule = priv->getObject();
310
311         if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_FREQUENCY)) {
312             std::string frequency = converter.toString(value);
313             rrule->setFrequency(converter.toRecurrenceFrequency(frequency));
314             return true;
315         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_INTERVAL)) {
316             int interval = converter.toInt(value);
317             rrule->setInterval(interval);
318             return true;
319         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_UNTIL_DATE)) {
320             if (!JSValueIsObjectOfClass(context, value, JSTZDate::getClassRef())) {
321                 ThrowMsg(ConversionException, "Wrong untilDate type.");
322             }
323             TimeUtilConverter timeConverter(context);
324             long long int untilDate = (long long int) (timeConverter.getTimeInMilliseconds(value)/1000);
325             rrule->setEndDate(untilDate);
326 /*
327             if( rrule->getTimeZone().empty() ) {
328                 std::string timeZone = timeConverter.getPropertiesInTZDate(value).timezone;
329                 rrule->setTimeZone(timeZone);
330             }
331 */
332             return true;
333         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_OCCURRENCE_COUNT)) {
334             long occurrenceCount = converter.toLong(value);
335             rrule->setOccurrenceCount(occurrenceCount);
336             return true;
337         /*} else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_MONTH)) {
338             std::vector<int> daysOfTheMonth = converter.toVectorOfInts(value);
339             rrule->setDaysOfTheMonth(daysOfTheMonth);
340             return true;*/
341         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_WEEK)) {
342             rrule->setDaysOfTheWeek(converter.toStringArray(value));
343             return true;
344         /*} else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_DAYS_OF_THE_YEAR)) {
345             std::vector<int> daysOfTheYear = converter.toVectorOfInts(value);
346             rrule->setDaysOfTheYear(daysOfTheYear);
347             return true;
348         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_WEEKS_OF_THE_YEAR)) {
349             std::vector<int> weekOfTheYear = converter.toVectorOfInts(value);
350             rrule->setWeeksOfTheYear(weekOfTheYear);
351             return true;*/
352         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_SET_POSITIONS)) {
353             rrule->setSetPositions(converter.toNumberArray(value));
354             return true;
355         } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_RECURRENCE_RULE_EXCEPTIONS)) {
356             rrule->setExceptions(converter.toTZDateArray(value));
357             return true;
358         }
359     }
360     Catch(Exception)
361     {
362                 LoggerW("Exception: "<<_rethrown_exception.GetMessage());
363     }
364
365     return true;
366 }
367
368 }
369 }