tizen 2.3 release
[framework/web/wearable/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 <JavaScriptCore/JavaScript.h>
22 #include "JSTimeDuration.h"
23 #include "TimeDuration.h"
24 #include <ArgumentValidator.h>
25 #include <Logger.h>
26 #include <JSUtil.h>
27 #include <JSWebAPIErrorFactory.h>
28 #include <PlatformException.h>
29
30 #ifdef IMPL_BACKWARD_COMPATIBLE
31 #include <CommonsJavaScript/Validator.h>
32 #include <Commons/Exception.h>
33 #endif // IMPL_BACKWARD_COMPATIBLE
34
35 using namespace DeviceAPI::Common;
36
37 namespace DeviceAPI {
38 namespace Time {
39
40 struct TimeDurationHolder {
41     TimeDurationPtr ptr;
42 };
43
44 namespace {
45 const char* CLASS_NAME = "TimeDuration";
46
47 const char* TIMEDURATION_ATTRIBUTE_API_LENGTH = "length";
48 const char* TIMEDURATION_ATTRIBUTE_API_UNIT = "unit";
49
50 const char* TIMEDURATION_FUNCTION_API_DIFFERENCE = "difference";
51 const char* TIMEDURATION_FUNCTION_API_EQUALS_TO = "equalsTo";
52 const char* TIMEDURATION_FUNCTION_API_LESS_THAN = "lessThan";
53 const char* TIMEDURATION_FUNCTION_API_GREATER_THAN = "greaterThan";
54 }
55
56 JSClassDefinition JSTimeDuration::m_classInfo = {
57         0,
58         kJSClassAttributeNone,
59         CLASS_NAME,
60         0,
61         JSTimeDuration::m_property,
62         JSTimeDuration::m_function,
63         JSTimeDuration::initialize,
64         JSTimeDuration::finalize,
65         NULL, //HasProperty,
66         NULL, //GetProperty,
67         NULL, //SetProperty,
68         NULL, //DeleteProperty,
69         NULL, //GetPropertyNames,
70         NULL, //CallAsFunction,
71         NULL, //CallAsConstructor,
72         NULL,
73         NULL, //ConvertToType
74 };
75
76 JSStaticValue JSTimeDuration::m_property[] = {
77         { TIMEDURATION_ATTRIBUTE_API_LENGTH, getLength, setLength,
78                 kJSPropertyAttributeDontDelete },
79         { TIMEDURATION_ATTRIBUTE_API_UNIT, getUnit, setUnit,
80                 kJSPropertyAttributeDontDelete },
81         { 0, 0, 0, 0 }
82 };
83
84 JSStaticFunction JSTimeDuration::m_function[] = {
85         {TIMEDURATION_FUNCTION_API_DIFFERENCE, difference, kJSPropertyAttributeNone },
86         {TIMEDURATION_FUNCTION_API_EQUALS_TO, equalsTo, kJSPropertyAttributeNone },
87         {TIMEDURATION_FUNCTION_API_LESS_THAN, lessThan, kJSPropertyAttributeNone },
88         {TIMEDURATION_FUNCTION_API_GREATER_THAN, greaterThan, kJSPropertyAttributeNone },
89         { 0, 0, 0 }
90 };
91
92 const JSClassDefinition* JSTimeDuration::getClassInfo()
93 {
94     return &m_classInfo;
95 }
96
97 JSClassRef JSTimeDuration::m_jsClassRef = JSClassCreate(JSTimeDuration::getClassInfo());
98
99 const JSClassRef JSTimeDuration::getClassRef()
100 {
101     if (!m_jsClassRef) {
102         m_jsClassRef = JSClassCreate(&m_classInfo);
103     }
104     return m_jsClassRef;
105 }
106
107 void JSTimeDuration::initialize(JSContextRef context, JSObjectRef object)
108 {
109     LOGD("Entered initialize");
110 }
111
112 void JSTimeDuration::finalize(JSObjectRef object)
113 {
114     LOGD("Entered finalize");
115     TimeDurationHolder *priv = static_cast<TimeDurationHolder*>(JSObjectGetPrivate(object));
116     if (priv) {
117         JSObjectSetPrivate(object, NULL);
118         delete priv;
119     }
120 }
121
122 TimeDurationPtr JSTimeDuration::getPrivateObject(JSContextRef context, JSValueRef value) {
123     LOGD("Entered");
124     if (!JSValueIsObjectOfClass(context, value, getClassRef())) {
125         LOGE("Type mismatch");
126         throw TypeMismatchException("Type mismatch");
127     }
128     JSObjectRef object = JSUtil::JSValueToObject(context, value);
129     TimeDurationHolder* priv = static_cast<TimeDurationHolder*>(JSObjectGetPrivate(object));
130     if (!priv or !priv->ptr) {
131         LOGE("Priv is null");
132         throw UnknownException("Priv is null");
133     }
134     return priv->ptr;
135 }
136
137 void JSTimeDuration::setPrivateObject(JSObjectRef object, TimeDurationPtr native) {
138     LOGD("Entered");
139     TimeDurationHolder* priv = static_cast<TimeDurationHolder*>(JSObjectGetPrivate(object));
140     if (!priv) {
141         LOGE("Priv is null");
142         throw UnknownException("Priv is null");
143     }
144     priv->ptr = native;
145 }
146
147 JSObjectRef JSTimeDuration::makeJSObject(JSContextRef context, TimeDurationPtr native) {
148     LOGD("Entered");
149     if (!native) {
150         LOGE("Native is null");
151         throw UnknownException("Native is null");
152     }
153     TimeDurationHolder* priv = new(std::nothrow) TimeDurationHolder();
154     if (!priv) {
155         LOGE("Memory allocation for priv failed");
156         throw UnknownException("Memory allocation for priv failed");
157     }
158     priv->ptr = native;
159
160     JSObjectRef obj = JSObjectMake(context, getClassRef(), static_cast<void*>(priv));
161     return obj;
162 }
163
164 JSValueRef JSTimeDuration::getLength(JSContextRef context,
165         JSObjectRef object,
166         JSStringRef propertyName,
167         JSValueRef* exception)
168 {
169     LOGD("Entered getLength()");
170     try {
171         TimeDurationPtr priv = getPrivateObject(context, object);
172         return JSUtil::toJSValueRef(context, priv->getLength());
173     }
174     catch (const BasePlatformException &err) {
175         LOGE("Failed to get time duration length. %s : %s", err.getName().c_str(),
176                 err.getMessage().c_str());
177     }
178     return JSValueMakeUndefined(context);
179 }
180
181 JSValueRef JSTimeDuration::getUnit(JSContextRef context,
182         JSObjectRef object,
183         JSStringRef propertyName,
184         JSValueRef* exception)
185 {
186     LOGD("Entered");
187     try {
188         TimeDurationPtr priv = getPrivateObject(context, object);
189         return JSUtil::toJSValueRef(context, priv->getUnit());
190     }
191     catch (const BasePlatformException &err) {
192         LOGE("Failed to get time duration unit. %s : %s", err.getName().c_str(),
193                 err.getMessage().c_str());
194     }
195     return JSValueMakeUndefined(context);
196 }
197
198 bool JSTimeDuration::setLength(JSContextRef context,
199         JSObjectRef object,
200         JSStringRef propertyName,
201         JSValueRef value,
202         JSValueRef* exception)
203 {
204     LOGD("Entered setLength()");
205     try {
206         TimeDurationPtr priv = getPrivateObject(context, object);
207         long long val = JSUtil::JSValueToLongLong(context, value);
208         priv->setLength(val);
209     }
210     catch (const BasePlatformException &err) {
211         LOGE("Failed to set time duration length. %s : %s", err.getName().c_str(),
212                 err.getMessage().c_str());
213     }
214     return true;
215 }
216
217 bool JSTimeDuration::setUnit(JSContextRef context,
218         JSObjectRef object,
219         JSStringRef propertyName,
220         JSValueRef value,
221         JSValueRef* exception)
222 {
223     LOGD("Entered");
224     try {
225         TimeDurationPtr priv = getPrivateObject(context, object);
226         if (!JSValueIsNull(context, value)) {
227             std::string unit = JSUtil::JSValueToString(context, value);
228             if (unit != MSECS && unit != SECS && unit != MINS &&
229                     unit != HOURS && unit != DAYS) {
230                 LOGE("Invalid unit");
231                 throw TypeMismatchException("Invalid unit");
232             }
233             priv->setUnit(unit);
234         }
235     }
236     catch (const BasePlatformException &err) {
237         LOGE("Failed to set time duration unit. %s : %s", err.getName().c_str(),
238                 err.getMessage().c_str());
239     }
240     return true;
241 }
242
243 JSObjectRef JSTimeDuration::constructor(JSContextRef context,
244         JSObjectRef constructor,
245         size_t argumentCount,
246         const JSValueRef arguments[],
247         JSValueRef* exception)
248 {
249     LOGD("Entered constructor()");
250     ArgumentValidator validator(context, argumentCount, arguments);
251     JSObjectRef obj = JSObjectMake(context, getClassRef(), NULL);
252
253     JSStringRef ctorName = JSStringCreateWithUTF8CString("constructor");
254     JSObjectSetProperty(context, obj, ctorName, constructor, kJSPropertyAttributeReadOnly
255             | kJSPropertyAttributeDontDelete | kJSPropertyAttributeDontEnum, NULL);
256     JSStringRelease(ctorName);
257
258     try {
259         TimeDurationPtr priv = TimeDurationPtr(new (std::nothrow) TimeDuration());
260         if (!priv) {
261             LOGW("Failed to create TimeDurationPtr object.");
262             throw UnknownException("Failed to create TimeDurationPtr object.");
263         }
264         priv->setLength(validator.toLongLong(0, false, 0));
265         priv->setUnit(validator.toString(1, true, MSECS));
266
267         TimeDurationHolder *holder = new (std::nothrow) TimeDurationHolder();
268         if (!holder) {
269             LOGW("Failed to create TimeDurationHolder object.");
270             throw UnknownException("Failed to create TimeDurationHolder object.");
271         }
272         holder->ptr = priv;
273         JSObjectSetPrivate(obj, static_cast<void*>(holder));
274     }
275     catch (const BasePlatformException &error) {
276         LOGE("%s : %s", error.getName().c_str(), error.getMessage().c_str());
277     }
278     catch (...) {
279         LOGE("An error occured");
280     }
281     return obj;
282 }
283
284 JSValueRef JSTimeDuration::difference(JSContextRef context,
285         JSObjectRef function,
286         JSObjectRef thisObject,
287         size_t argumentCount,
288         const JSValueRef arguments[],
289         JSValueRef * exception)
290 {
291     LOGD("Entered difference()");
292
293     TimeDurationPtr diff;
294     try {
295         TimeDurationPtr priv = getPrivateObject(context, thisObject);
296         ArgumentValidator validator(context, argumentCount, arguments);
297         // TimeDuration other
298         JSObjectRef otherObj = validator.toObject(0, JSTimeDuration::getClassRef());
299         TimeDurationPtr other = getPrivateObject(context, otherObj);
300
301         return JSTimeDuration::makeJSObject(context,priv->difference(other));
302     }
303     catch (const BasePlatformException &err) {
304         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
305         return JSWebAPIErrorFactory::postException(context, exception, err);
306     }
307     catch (...) {
308         UnknownException err("Unknown Error in tizen."
309                 "TimeDuration.difference().");
310         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
311         return JSWebAPIErrorFactory::postException(context, exception, err);
312     }
313 }
314
315 JSValueRef JSTimeDuration::equalsTo(JSContextRef context,
316         JSObjectRef function,
317         JSObjectRef thisObject,
318         size_t argumentCount,
319         const JSValueRef arguments[],
320         JSValueRef * exception)
321 {
322     LOGD("Entered equalsTo()");
323
324     try {
325         TimeDurationPtr priv = getPrivateObject(context, thisObject);
326         ArgumentValidator validator(context, argumentCount, arguments);
327         // TimeDuration other
328         JSObjectRef otherObj = validator.toObject(0, JSTimeDuration::getClassRef());
329         TimeDurationPtr other = getPrivateObject(context, otherObj);
330
331         return JSUtil::toJSValueRef(context, priv->equalsTo(other));
332     }
333     catch (const BasePlatformException &err) {
334         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
335         return JSWebAPIErrorFactory::postException(context, exception, err);
336     }
337     catch (...) {
338         UnknownException err("Unknown Error in tizen.download.start().");
339         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
340         return JSWebAPIErrorFactory::postException(context, exception, err);
341     }
342 }
343
344 JSValueRef JSTimeDuration::lessThan(JSContextRef context,
345         JSObjectRef function,
346         JSObjectRef thisObject,
347         size_t argumentCount,
348         const JSValueRef arguments[],
349         JSValueRef * exception)
350 {
351     LOGD("Entered lessThan()");
352
353     try {
354         TimeDurationPtr priv = getPrivateObject(context, thisObject);
355         ArgumentValidator validator(context, argumentCount, arguments);
356         // TimeDuration other
357         JSObjectRef otherObj = validator.toObject(0, JSTimeDuration::getClassRef());
358         TimeDurationPtr other = getPrivateObject(context, otherObj);
359
360         return JSUtil::toJSValueRef(context, priv->lessThan(other));
361     }
362     catch (const BasePlatformException &err) {
363         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
364         return JSWebAPIErrorFactory::postException(context, exception, err);
365     }
366     catch (...) {
367         UnknownException err("Unknown Error in tizen.download.start().");
368         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
369         return JSWebAPIErrorFactory::postException(context, exception, err);
370     }
371 }
372
373 JSValueRef JSTimeDuration::greaterThan(JSContextRef context,
374         JSObjectRef function,
375         JSObjectRef thisObject,
376         size_t argumentCount,
377         const JSValueRef arguments[],
378         JSValueRef * exception)
379 {
380     LOGD("Entered greaterThan()");
381
382     try {
383         TimeDurationPtr priv = getPrivateObject(context, thisObject);
384         ArgumentValidator validator(context, argumentCount, arguments);
385         // TimeDuration other
386         JSObjectRef otherObj = validator.toObject(0, JSTimeDuration::getClassRef());
387         TimeDurationPtr other = getPrivateObject(context, otherObj);
388
389         return JSUtil::toJSValueRef(context, priv->greaterThan(other));
390     }
391     catch (const BasePlatformException &err) {
392         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
393         return JSWebAPIErrorFactory::postException(context, exception, err);
394     }
395     catch (...) {
396         UnknownException err("Unknown Error in tizen.download.start().");
397         LOGE("%s : %s", err.getName().c_str(), err.getMessage().c_str());
398         return JSWebAPIErrorFactory::postException(context, exception, err);
399     }
400 }
401
402 #ifdef IMPL_BACKWARD_COMPATIBLE
403 JSObjectRef JSTimeDuration::createJSObject(JSContextRef context,
404         const DurationProperties &durations)
405 {
406     DurationPropertiesPtr durationProps(new DurationProperties(durations));
407     TimeDurationPrivObject *priv = new TimeDurationPrivObject(context, durationProps);
408
409     if (!priv) {
410         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Can not new an object");
411     }
412     return JSObjectMake(context, getClassRef(), priv);
413 }
414
415 JSObjectRef JSTimeDuration::createJSObject(JSContextRef context,
416         const DurationPropertiesPtr duration)
417 {
418     TimeDurationPrivObject *priv = new TimeDurationPrivObject(context, duration);
419     if (!priv) {
420         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null.");
421     }
422     return JSObjectMake(context, getClassRef(), priv);
423 }
424 #endif // IMPL_BACKWARD_COMPATIBLE
425
426 } //Time
427 } //DeviceAPI