wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / TimeUtil / JSTimeDuration.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 <string>
19 #include <memory>
20 #include <cmath>
21 #include <Commons/Exception.h>
22 #include <CommonsJavaScript/Utils.h>
23 #include <CommonsJavaScript/JSCallbackManager.h>
24 #include <JSTizenExceptionFactory.h>
25 #include <JSTizenException.h>
26 #include "JSTimeDuration.h"
27 #include "TimeUtilConverter.h"
28 #include <Logger.h>
29
30 namespace DeviceAPI {
31 namespace Time {
32
33 using namespace DPL;
34 using namespace DeviceAPI::Common;
35 using namespace WrtDeviceApis::Commons;
36 using namespace WrtDeviceApis::CommonsJavaScript;
37
38 #define TIZEN_TIMEDURATION_LENGTH "length"
39 #define TIZEN_TIMEDURATION_UNIT "unit"
40
41 JSClassDefinition JSTimeDuration::m_classInfo = {
42     0,
43     kJSClassAttributeNone,
44     "TimeDuration",
45     0,
46     m_property,
47     m_function,
48     initialize,
49     finalize,
50     NULL, //HasProperty,
51     NULL, //GetProperty,
52     setProperty, //SetProperty,
53     NULL, //DeleteProperty,
54     NULL, //GetPropertyNames,
55     NULL, //CallAsFunction,
56     NULL, //CallAsConstructor,
57     NULL,
58     NULL, //ConvertToType
59 };
60
61
62 JSStaticFunction JSTimeDuration::m_function[] = {
63     {"difference",           JSTimeDuration::difference,            kJSPropertyAttributeNone},
64     {"equalsTo",           JSTimeDuration::equalsTo,            kJSPropertyAttributeNone},
65     {"lessThan",           JSTimeDuration::lessThan,            kJSPropertyAttributeNone},
66     {"greaterThan",           JSTimeDuration::greaterThan,            kJSPropertyAttributeNone},
67 };
68
69 JSStaticValue JSTimeDuration::m_property[] =
70 {
71     //TimdDurationProperties
72         {TIZEN_TIMEDURATION_LENGTH,  getProperty, setProperty, kJSPropertyAttributeNone},
73         {TIZEN_TIMEDURATION_UNIT,  getProperty, setProperty, kJSPropertyAttributeNone},
74         { 0, 0, 0, 0 }
75 };
76
77 const JSClassRef JSTimeDuration::getClassRef()
78 {
79     if (!m_jsClassRef) {
80         m_jsClassRef = JSClassCreate(&m_classInfo);
81     }
82     return m_jsClassRef;
83 }
84
85 const JSClassDefinition* JSTimeDuration::getClassInfo()
86 {
87     return &m_classInfo;
88 }
89
90 JSClassRef JSTimeDuration::m_jsClassRef = JSClassCreate(JSTimeDuration::getClassInfo());
91
92 void JSTimeDuration::initialize(JSContextRef context, JSObjectRef object)
93 {
94         LoggerD("entered Nothing to do.");
95 }
96
97 void JSTimeDuration::finalize(JSObjectRef object)
98 {
99         TimeDurationPrivObject* priv = static_cast<TimeDurationPrivObject*>(JSObjectGetPrivate(object));
100         JSObjectSetPrivate(object, NULL);
101         LoggerD("Deleting TimeDuration");
102         delete priv;
103 }
104
105 JSValueRef JSTimeDuration::getProperty(JSContextRef context, JSObjectRef object,
106         JSStringRef propertyName, JSValueRef* exception)
107 {
108         LoggerD("Enter");
109
110         Try     {
111                 TimeUtilConverter convert(context);
112
113                 LoggerD("propertyName : " << convert.toString(propertyName));
114                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_TIMEDURATION_LENGTH)) {
115                         return convert.toJSValueRef(static_cast<double>(convert.getDurationLength(object)));
116                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_TIMEDURATION_UNIT)) {
117                         std::string strUnit = convert.toDurationUnitString(convert.getDurationUnit(object));
118                         if (strUnit == "")
119                                 ThrowMsg(InvalidArgumentException, "unit string is invald.");
120                         return convert.toJSValueRef(strUnit);
121                 }
122         } Catch (ConversionException) {
123                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
124         } Catch (InvalidArgumentException) {
125                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
126         } Catch (WrtDeviceApis::Commons::Exception) {
127                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
128         }
129         return JSValueMakeUndefined(context);
130 }
131
132 bool JSTimeDuration::setProperty(JSContextRef context, JSObjectRef object,
133         JSStringRef propertyName, JSValueRef value,  JSValueRef* exception)
134 {
135         LoggerD("Enter");
136
137         Try     {
138                 TimeDurationPrivObject* privateObject = static_cast<TimeDurationPrivObject*>(JSObjectGetPrivate(object));
139                 if (!privateObject) {
140                         LoggerE("Private object is not set.");
141                         ThrowMsg(NullPointerException, "Private object not initialized");
142                 }
143
144                 DurationPropertiesPtr duration = privateObject->getObject();
145                 TimeUtilConverter convert(context);
146
147                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_TIMEDURATION_LENGTH)) {
148                         duration->length = convert.toLongLong(value);
149                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_TIMEDURATION_UNIT)) {
150                         short unit = convert.toDurationUnit(convert.toString(value));
151                         if (unit == 0xff)
152                                 ThrowMsg(ConversionException, "property doesn't exist.");
153                         duration->unit = unit;
154                 } else
155                         return false;
156
157                 return true;
158         } Catch (NullPointerException) {
159                 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
160                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
161         } Catch (ConversionException) {
162                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
163                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
164         } Catch (InvalidArgumentException) {
165                 LoggerE("InvalidArgumentException: " << _rethrown_exception.GetMessage());
166                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
167         } Catch (WrtDeviceApis::Commons::Exception) {
168                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
169                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
170         }
171         return false;
172 }
173
174 JSObjectRef JSTimeDuration::createJSObject(JSContextRef context,
175         const DurationProperties &durations)
176 {
177     DurationPropertiesPtr durationProps(new DurationProperties(durations));
178     TimeDurationPrivObject *priv = new TimeDurationPrivObject(context, durationProps);
179
180     if (!priv) {
181         ThrowMsg(NullPointerException, "Can not new an object");
182     }
183     return JSObjectMake(context, getClassRef(), priv);
184 }
185
186 JSObjectRef JSTimeDuration::constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
187         LoggerD("entered");
188         TimeUtilConverter convert(ctx);
189         Try {
190                 DurationProperties duration;
191                 if (argumentCount == 0)
192                         duration.length = convert.toLongLong(JSValueMakeUndefined(ctx));
193                 else
194                         duration.length = convert.toLongLong(arguments[0]);
195
196                 if (argumentCount > 1) {
197                         if (!JSValueIsUndefined(ctx, arguments[1]) && !JSValueIsNull(ctx, arguments[1])) {
198                                 std::string unit = convert.toString(arguments[1]);
199                                 duration.unit = convert.toDurationUnit(unit);
200                                 if (duration.unit == 0xff)
201                                         ThrowMsg(ConversionException, "Argument(unit) is invalid(wrong type unit)");
202                         }
203                 }
204                 JSObjectRef timeDuration = createJSObject(ctx, duration);
205                 if (timeDuration) {
206                         JSStringRef ctorName = JSStringCreateWithUTF8CString("constructor");
207                     JSObjectSetProperty(ctx, timeDuration, ctorName, constructor,
208                         kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete | kJSPropertyAttributeDontEnum, NULL);
209                 JSStringRelease(ctorName);
210                         return timeDuration;
211                 }
212         } Catch(NullPointerException) {
213                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
214                 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
215                 *exception = error;
216                 return error;
217         } Catch(UnknownException) {
218                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
219                 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
220                 *exception = error;
221                 return error;
222         } Catch(ConversionException) {
223                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
224                 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
225                 *exception = error;
226                 return error;
227         } Catch (InvalidArgumentException) {
228                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
229                 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
230                 *exception = error;
231                 return error;
232         } Catch (WrtDeviceApis::Commons::Exception) {
233             LoggerW("Trying to get incorrect value");
234         }
235         JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
236         *exception = error;
237         return error;
238
239 }
240
241 JSValueRef JSTimeDuration::diffTimeDuration(JSContextRef context, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception, CompareType type) {
242         LoggerD("entered");
243
244         TimeDurationPrivObject* privateObject = static_cast<TimeDurationPrivObject*>(JSObjectGetPrivate(thisObject));
245         if (!privateObject) {
246                 LoggerE("Private object is not set.");
247                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
248         }
249
250         TimeUtilConverter converter(context);
251
252         DurationProperties first = converter.getDurationPropertis(thisObject);
253         DurationProperties second;
254         if (argumentCount == 0)
255                 second= converter.getDurationPropertis(JSValueMakeUndefined(context));
256         else
257                 second= converter.getDurationPropertis(arguments[0]);
258
259         DurationProperties diff;
260         if (first.unit > second.unit) {
261                 long long firstLength = converter.convertDurationLength(first, second.unit);
262                 diff.unit = second.unit;
263                 diff.length = firstLength - second.length;
264         } else {
265                 long long secondLength = converter.convertDurationLength(second, first.unit);
266                 diff.unit = first.unit;
267                 diff.length = first.length - secondLength;
268         }
269
270         switch (type) {
271                 case EQUALSTO:
272                 {
273                         if (diff.length == 0)
274                                 return converter.toJSValueRef(true);
275                         else
276                                 return converter.toJSValueRef(false);
277                 }
278                 case LESSTHAN:
279                 {
280                         if (diff.length < 0)
281                                 return converter.toJSValueRef(true);
282                         else
283                                 return converter.toJSValueRef(false);
284                 }
285                 case GREATERTHAN:
286                 {
287                         if (diff.length > 0)
288                                 return converter.toJSValueRef(true);
289                         else
290                                 return converter.toJSValueRef(false);
291                 }
292                 case DIFFERENCE:
293                 default:
294                         return converter.makeDurationObject(diff);
295         }
296 }
297
298 JSValueRef JSTimeDuration::difference(JSContextRef context, JSObjectRef function, 
299         JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) {
300         LoggerD("Entered");
301         Try {
302                 return diffTimeDuration(context, thisObject, argumentCount, arguments, exception, DIFFERENCE);
303         } Catch(ConversionException) {
304                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
305                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
306         } Catch (InvalidArgumentException) {
307                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
308                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
309         } Catch (UnsupportedException) {
310                 LoggerE("JSTimeUtil::hasInstance NotSupportedException");
311                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR , "Not Support");
312         } Catch (PlatformException) {
313                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
314         } Catch (WrtDeviceApis::Commons::Exception) {
315                 LoggerE("Exception: " << _rethrown_exception.GetMessage());             
316         }
317         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
318 }
319
320 JSValueRef JSTimeDuration::equalsTo(JSContextRef context, JSObjectRef function, 
321         JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) {
322         LoggerD("Entered");
323         Try {
324                 return diffTimeDuration(context, thisObject, argumentCount, arguments, exception, EQUALSTO);
325         } Catch(ConversionException) {
326                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
327                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
328         } Catch (InvalidArgumentException) {
329                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
330                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
331         } Catch (UnsupportedException) {
332                 LoggerE("JSTimeUtil::hasInstance NotSupportedException");
333                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR , "Not Support");
334         } Catch (PlatformException) {
335                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
336         } Catch (WrtDeviceApis::Commons::Exception) {
337                 LoggerE("Exception: " << _rethrown_exception.GetMessage());                     
338         }
339         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
340 }
341
342 JSValueRef JSTimeDuration::lessThan(JSContextRef context, JSObjectRef function, 
343         JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) {
344         LoggerD("Entered");
345         Try {
346                 return diffTimeDuration(context, thisObject, argumentCount, arguments, exception, LESSTHAN);
347         } Catch(ConversionException) {
348                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
349                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
350         } Catch (InvalidArgumentException) {
351                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
352                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
353         } Catch (UnsupportedException) {
354                 LoggerE("JSTimeUtil::hasInstance NotSupportedException");
355                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR , "Not Support");
356         } Catch (PlatformException) {
357                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
358         } Catch (WrtDeviceApis::Commons::Exception) {
359                 LoggerE("Exception: " << _rethrown_exception.GetMessage());             
360         }
361         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
362 }
363
364 JSValueRef JSTimeDuration::greaterThan(JSContextRef context, JSObjectRef function, 
365         JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) {
366         LoggerD("Entered");
367         Try {
368                 return diffTimeDuration(context, thisObject, argumentCount, arguments, exception, GREATERTHAN);
369         } Catch(ConversionException) {
370                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
371                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
372         } Catch (InvalidArgumentException) {
373                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
374                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
375         } Catch (UnsupportedException) {
376                 LoggerE("JSTimeUtil::hasInstance NotSupportedException");
377                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR , "Not Support");
378         } Catch (PlatformException) {
379                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
380         } Catch (WrtDeviceApis::Commons::Exception) {
381                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
382         }
383         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
384 }
385
386 } //Time
387 } //DeviceAPI