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