1398b0906238700fd5191324b6e5cd5dacc718f1
[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     NULL, //SetProperty,
57     NULL, //DeleteProperty,
58     NULL, //GetPropertyNames,
59     NULL, //CallAsFunction,
60     constructor, //CallAsConstructor,
61     NULL,
62     NULL, //ConvertToType
63 };
64
65
66 JSStaticFunction JSTimeDuration::m_function[] = {
67     {"difference",           JSTimeDuration::difference,            kJSPropertyAttributeNone},
68 };
69
70 JSStaticValue JSTimeDuration::m_property[] =
71 {
72     //TimdDurationProperties
73         {TIZEN10_TIMEDURATION_LENGTH,  getProperty, setProperty, kJSPropertyAttributeNone},
74         {TIZEN10_TIMEDURATION_UNIT,  getProperty, setProperty, kJSPropertyAttributeNone},
75         { 0, 0, 0, 0 }
76 };
77
78 const JSClassRef JSTimeDuration::getClassRef()
79 {
80     if (!m_jsClassRef) {
81         m_jsClassRef = JSClassCreate(&m_classInfo);
82     }
83     return m_jsClassRef;
84 }
85
86 const JSClassDefinition* JSTimeDuration::getClassInfo()
87 {
88     return &m_classInfo;
89 }
90
91 JSClassRef JSTimeDuration::m_jsClassRef = JSClassCreate(JSTimeDuration::getClassInfo());
92
93 void JSTimeDuration::initialize(JSContextRef context, JSObjectRef object)
94 {
95         LogDebug("entered Nothing to do.");
96
97         if (!JSObjectGetPrivate(object)) {
98                 LogDebug("Private object not set... setting it.");
99                 DurationProperties durations;
100                 std::auto_ptr<DurationProperties> durationProps(new DurationProperties(
101                                                                    durations));
102                 TimeDurationPrivObject *priv = new TimeDurationPrivObject(context, durationProps.get());
103                 durationProps.release();
104                 if (!JSObjectSetPrivate(object, priv)) {
105                         delete priv;
106                 }
107         }
108 }
109
110 void JSTimeDuration::finalize(JSObjectRef object)
111 {
112         TimeDurationPrivObject* priv = static_cast<TimeDurationPrivObject*>(JSObjectGetPrivate(object));
113         JSObjectSetPrivate(object, NULL);
114         LogDebug("Deleting TimeDuration");
115         delete priv;
116 }
117
118 JSValueRef JSTimeDuration::getProperty(JSContextRef context, JSObjectRef object,
119         JSStringRef propertyName, JSValueRef* exception)
120 {
121         LogDebug("Enter");
122
123         Try     {
124                 TimeUtilConverter convert(context);
125
126                 LogDebug("propertyName : " << convert.toString(propertyName));
127                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN10_TIMEDURATION_LENGTH)) {
128                         return convert.toJSValueRef(static_cast<double>(convert.getDurationLength(object)));
129                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN10_TIMEDURATION_UNIT)) {
130                         std::string strUnit = convert.toDurationUnitString(convert.getDurationUnit(object));
131                         if (strUnit == "")
132                                 ThrowMsg(InvalidArgumentException, "unit string is invald.");
133                         return convert.toJSValueRef(strUnit);
134                 }
135         } Catch (ConversionException) {
136                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
137         } Catch (InvalidArgumentException) {
138                 LogError("Exception: " << _rethrown_exception.GetMessage());
139         } Catch (WrtDeviceApis::Commons::Exception) {
140                 LogError("Exception: " << _rethrown_exception.GetMessage());
141         }
142         return JSValueMakeUndefined(context);
143 }
144
145 bool JSTimeDuration::setProperty(JSContextRef context, JSObjectRef object,
146         JSStringRef propertyName, JSValueRef value,  JSValueRef* exception)
147 {
148         LogDebug("Enter");
149
150         Try     {
151                 TimeDurationPrivObject* privateObject = static_cast<TimeDurationPrivObject*>(JSObjectGetPrivate(object));
152                 if (!privateObject) {
153                         LogError("Private object is not set.");
154                         ThrowMsg(NullPointerException, "Private object not initialized");
155                 }
156
157                 DurationProperties *duration = privateObject->getObject();
158                 TimeUtilConverter convert(context);
159
160                 if (JSValueIsNull(context, value) || JSValueIsUndefined(context, value)) {
161                         LogError("value is invald.");
162                         ThrowMsg(ConversionException, "value is invald.");
163                 }
164                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN10_TIMEDURATION_LENGTH)) {
165                         if (!JSValueIsNumber(context, value)) {
166                                 LogError("value is invald.");
167                                 ThrowMsg(ConversionException, "value is invald.");
168                         }
169                         duration->length = static_cast<long long>(convert.toDouble(value));
170                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN10_TIMEDURATION_UNIT)) {
171                         if (!JSValueIsString(context, value)) {
172                                 LogError("value is invald.");
173                                 ThrowMsg(ConversionException, "value is invald.");
174                         }
175                         short unit = convert.toDurationUnit(convert.toString(value));
176                         if (unit == 0xff)
177                                 ThrowMsg(InvalidArgumentException, "property doesn't exist.");
178                         duration->unit = unit;
179                 } else
180                         ThrowMsg(InvalidArgumentException, "property doesn't exist.");
181
182                 return true;
183         } Catch (NullPointerException) {
184                 LogError("NullPointerException: " << _rethrown_exception.GetMessage());
185         } Catch (ConversionException) {
186                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
187         } Catch (InvalidArgumentException) {
188                 LogError("InvalidArgumentException: " << _rethrown_exception.GetMessage());
189         } Catch (WrtDeviceApis::Commons::Exception) {
190                 LogError("Exception: " << _rethrown_exception.GetMessage());
191         }
192         return false;
193 }
194
195 JSObjectRef JSTimeDuration::createJSObject(JSContextRef context,
196         const DurationProperties &durations)
197 {
198     std::auto_ptr<DurationProperties> durationProps(new DurationProperties(
199                                                        durations));
200     TimeDurationPrivObject *priv = new TimeDurationPrivObject(context, durationProps.get());
201     durationProps.release();
202     if (!priv) {
203         ThrowMsg(NullPointerException, "Can not new an object");
204     }
205     return JSObjectMake(context, getClassRef(), priv);
206 }
207
208 JSObjectRef JSTimeDuration::constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
209         LogDebug("entered");
210         TimeUtilConverter convert(ctx);
211         Try {
212                 if ((argumentCount < 1) || (argumentCount > 2)) {
213                         LogError("Wrong argument count");
214                         ThrowMsg(InvalidArgumentException, "Wrong TimeDuration argumentCount");
215                 }
216
217                 TimeDurationPrivObject* mainPriv = static_cast<TimeDurationPrivObject*>(JSObjectGetPrivate(constructor));
218                 JSContextRef global_context = mainPriv ? mainPriv->getContext() : ctx;
219
220                 DurationProperties duration;
221                 if (JSValueIsNull(ctx, arguments[0]) || JSValueIsUndefined(ctx, arguments[0]) || !JSValueIsNumber(ctx, arguments[0])) {
222                         ThrowMsg(ConversionException, "Argument(length) is invalid");
223                 }
224                 duration.length = convert.toDouble(arguments[0]);
225                 if (argumentCount == 2) {
226                         if (JSValueIsUndefined(ctx, arguments[1]) || !JSValueIsString(ctx, arguments[1])) {
227                                 ThrowMsg(ConversionException, "Argument(unit) is invalid");
228                         } else if (!JSValueIsNull(ctx, arguments[1])) {
229                                 std::string unit = convert.toString(arguments[1]);
230                                 duration.unit = convert.toDurationUnit(unit);
231                                 if (duration.unit == 0xff)
232                                         ThrowMsg(InvalidArgumentException, "Argument(unit) is invalid(wrong type unit)");
233                         }
234                 }
235                 return createJSObject(global_context, duration);
236         } Catch(NullPointerException) {
237                 LogError("Exception: " << _rethrown_exception.GetMessage());
238                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
239                 return NULL;
240         } Catch(UnknownException) {
241                 LogError("Exception: " << _rethrown_exception.GetMessage());
242                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
243                 return NULL;
244         } Catch(ConversionException) {
245                 LogError("Exception: " << _rethrown_exception.GetMessage());
246                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
247                 return NULL;
248         } Catch (InvalidArgumentException) {
249                 LogError("Exception: " << _rethrown_exception.GetMessage());
250                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
251                 return NULL;
252         } Catch (WrtDeviceApis::Commons::Exception) {
253             LogWarning("Trying to get incorrect value");
254         }
255         *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
256         return NULL;
257 }
258
259 JSValueRef JSTimeDuration::difference(JSContextRef context, JSObjectRef function, 
260         JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef * exception) {
261         LogDebug("Entered");
262         Try {
263                 TimeDurationPrivObject* privateObject = static_cast<TimeDurationPrivObject*>(JSObjectGetPrivate(thisObject));
264
265                 if (argumentCount != 1) {
266                         LogError("Wrong parameters");
267                         ThrowMsg(InvalidArgumentException, "Wrong parameters");
268                 }
269
270                 AceSecurityStatus status = TIMEUTIL_CHECK_ACCESS(
271                         privateObject->getContext(),
272                         TIMEUTIL_FUNCTION_API_READ_FUNCS);
273                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
274                 
275                 TimeUtilConverter converter(privateObject->getContext());
276
277                 DurationProperties first = converter.getDurationPropertis(thisObject);
278                 DurationProperties second = converter.getDurationPropertis(arguments[0]);
279
280                 DurationProperties diff;
281                 if (first.unit > second.unit) {
282                         long long firstLength = converter.convertDurationLength(first, second.unit);
283                         diff.unit = second.unit;
284                         diff.length = firstLength - second.length;
285                 } else {
286                         long long secondLength = converter.convertDurationLength(second, first.unit);
287                         diff.unit = first.unit;
288                         diff.length = first.length - secondLength;
289                 }
290                 return converter.makeDurationObject(diff);
291         } Catch(ConversionException) {
292                 LogError("Exception: " << _rethrown_exception.GetMessage());
293                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
294         } Catch (InvalidArgumentException) {
295                 LogError("Exception: " << _rethrown_exception.GetMessage());
296                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
297         } Catch (UnsupportedException) {
298                 LogError("JSTimeUtil::hasInstance NotSupportedException");
299                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR , "Not Support");
300         } Catch (PlatformException) {
301                 LogError("Exception: " << _rethrown_exception.GetMessage());
302                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
303         } Catch (WrtDeviceApis::Commons::Exception) {
304                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");                    
305         }
306         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
307 }
308
309 } //Tizen1_0
310 } //TizenApis