Update change log and spec for wrt-plugins-tizen_0.4.11
[framework/web/wrt-plugins-tizen.git] / src / Contact / JSContactPhoneNumber.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 /**
19  * @file        JSContactPhoneNumber.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @brief       Implementation of the JSContactPhoneNumber class
23  */
24
25 #include <dpl/log/log.h>
26 #include <dpl/shared_ptr.h>
27 #include <CommonsJavaScript/Validator.h>
28 #include <JSTizenExceptionFactory.h>
29 #include <JSTizenException.h>
30 #include "ContactConverter.h"
31 #include "JSContactPhoneNumberTypeArray.h"
32 #include "JSContactPhoneNumber.h"
33
34 #define FILTER_CLASS_NAME "ContactPhoneNumber"
35
36 #define CONTACT_ATTR_NUMBER "number"
37 #define CONTACT_ATTR_TYPES "types"
38 #define CONTACT_ATTR_IS_DEFAULT "isDefault"
39
40 namespace DeviceAPI {
41 namespace Contact {
42
43 using namespace DeviceAPI::Common;
44 using namespace WrtDeviceApis::Commons;
45 using namespace WrtDeviceApis::CommonsJavaScript;
46
47 JSClassDefinition JSContactPhoneNumber::m_classInfo =
48 {
49         0,
50         kJSClassAttributeNone,
51         FILTER_CLASS_NAME,
52         NULL,
53         m_property,
54         m_functions,
55         Initialize,
56         Finalize,
57         NULL, //hasProperty,
58         NULL, //GetProperty,
59         NULL, //SetProperty,
60         NULL, //DeleteProperty,
61         NULL, //getPropertyNames,
62         NULL, //CallAsFunction,
63         constructor, //CallAsConstructor,
64         hasInstance, //HasInstance,
65         NULL, //ConvertToType,
66 };
67
68 JSStaticValue JSContactPhoneNumber::m_property[] = {
69         { CONTACT_ATTR_NUMBER, getNumber, setNumber, kJSPropertyAttributeNone },
70         { CONTACT_ATTR_TYPES, getTypes, setTypes, kJSPropertyAttributeNone },
71         { CONTACT_ATTR_IS_DEFAULT, getIsDefault, setIsDefault, kJSPropertyAttributeNone },
72         { 0, 0, 0, 0 }
73 };
74
75 JSStaticFunction JSContactPhoneNumber::m_functions[] =
76 {
77         { 0, 0, 0 }
78 };
79
80 JSClassRef JSContactPhoneNumber::m_classRef = JSClassCreate(&m_classInfo);
81
82 JSClassRef JSContactPhoneNumber::getClassRef() {
83         if (!m_classRef) {
84                 m_classRef = JSClassCreate(&m_classInfo);
85         }
86         return m_classRef;
87 }
88
89 bool JSContactPhoneNumber::isObjectOfClass(JSContextRef context, JSValueRef value)
90 {
91         return JSValueIsObjectOfClass(context, value, getClassRef());
92 }
93
94 ContactPhoneNumberPtr JSContactPhoneNumber::getContactPhoneNumber(JSContextRef context, JSValueRef value)
95 {
96         if (!isObjectOfClass(context, value)) {
97                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
98         }
99         JSObjectRef object = JSValueToObject(context, value, NULL);
100         if (!object) {
101                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
102         }
103         JSContactPhoneNumberPriv *priv = static_cast<JSContactPhoneNumberPriv*>(JSObjectGetPrivate(object));
104         if (!priv) {
105                 Throw(WrtDeviceApis::Commons::NullPointerException);
106         }
107         return priv->getObject();
108 }
109
110 void JSContactPhoneNumber::Initialize(JSContextRef context, JSObjectRef object)
111 {
112         if (!JSObjectGetPrivate(object))
113         {
114                 ContactPhoneNumberPtr phoneNumber(new ContactPhoneNumber());
115                 JSContactPhoneNumberPriv *priv = new JSContactPhoneNumberPriv(context, ContactPhoneNumberPtr(phoneNumber));
116                 if (!JSObjectSetPrivate(object, priv)) {
117                         delete priv;
118                 }
119         }
120 }
121
122 void JSContactPhoneNumber::Finalize(JSObjectRef object)
123 {
124         JSContactPhoneNumberPriv *priv = static_cast<JSContactPhoneNumberPriv*>(JSObjectGetPrivate(object));
125
126         if (priv != NULL)
127                 delete (priv);
128 }
129
130 JSObjectRef JSContactPhoneNumber::createJSObject(JSContextRef context, ContactPhoneNumberPtr contactPhoneNumber)
131 {
132         JSContactPhoneNumberPriv *priv = new JSContactPhoneNumberPriv(context, contactPhoneNumber);
133         JSObjectRef jsObjectRef = JSObjectMake(context, getClassRef(), static_cast<void*>(priv));
134         if (NULL == jsObjectRef) {
135                 LogError("object creation error");
136                 return NULL;
137         }
138         return jsObjectRef;
139 }
140
141 ContactPhoneNumberPtr JSContactPhoneNumber::getPrivData(JSObjectRef object)
142 {
143         JSContactPhoneNumberPriv *priv = static_cast<JSContactPhoneNumberPriv*>(JSObjectGetPrivate(object));
144         if (!priv) {
145                 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
146         }
147         ContactPhoneNumberPtr result = priv->getObject();
148         if (!result) {
149                 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
150         }
151         return result;
152 }
153
154 JSObjectRef JSContactPhoneNumber::constructor(JSContextRef context,
155                 JSObjectRef constructor,
156                 size_t argumentCount,
157                 const JSValueRef arguments[],
158                 JSValueRef* exception)
159 {
160         LogDebug("entered");
161
162         bool js2ndParamIsArray = false;
163
164         JSContactPhoneNumberPriv *priv = static_cast<JSContactPhoneNumberPriv*>(JSObjectGetPrivate(constructor));
165         if (!priv) {
166                 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
167         }
168         JSContextRef gContext = priv->getContext();
169
170         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
171         Try {
172                 if (argumentCount >= 2)
173                 {
174                         if (JSIsArrayValue(gContext, arguments[1]))
175                                 js2ndParamIsArray = true;
176
177                         if (!js2ndParamIsArray &&
178                                         !JSValueIsNull(gContext, arguments[1]) &&
179                                         !JSValueIsUndefined(gContext, arguments[1]))
180                                 ThrowMsg(InvalidArgumentException, "2nd argument must be array of ContactPhoneNumber types");
181                 }
182
183         } Catch(Exception ) {
184                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
185                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "2nd argument must be array of ContactPhoneNumber types");
186                 return NULL;
187         }
188
189         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
190
191         std::string number;
192         ContactPhoneNumberTypeArrayPtr types(NULL);
193         bool isDefault;
194
195         Try {
196                 if(argumentCount >= 1)
197                         number = converter->toString(arguments[0]);
198                 else
199                         number = converter->toString(JSValueMakeUndefined(context));
200
201         } Catch(Exception) {
202                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
203                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Internal error");
204                 return NULL;
205         }
206
207         Try {
208                 if(js2ndParamIsArray)
209                         types = converter->toContactPhoneNumberTypeArray(arguments[1]);
210                 else
211                         types = ContactPhoneNumberTypeArrayPtr(new ContactPhoneNumberTypeArray());
212
213                 if(types->size() == 0)
214                         types->push_back(CONTACT_PHONE_NUMBER_TYPE_VOICE);
215
216         } Catch(Exception) {
217                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
218                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
219                 return NULL;
220         }
221
222         Try {
223                 if(argumentCount >= 3)
224                         isDefault = converter->toBool(arguments[2]);
225                 else
226                         isDefault = converter->toBool(JSValueMakeUndefined(context));
227
228         } Catch(Exception) {
229                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
230                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
231                 return NULL;
232         }
233
234         ContactPhoneNumberPtr contactPhoneNumber(new ContactPhoneNumber());
235         contactPhoneNumber->setNumber(number);
236         contactPhoneNumber->setTypes(types);
237         contactPhoneNumber->setIsDefault(isDefault);
238
239         JSObjectRef jsobject;
240
241         Try {
242                 jsobject = createJSObject(gContext, contactPhoneNumber);
243         } Catch(Exception) {
244                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
245                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
246                 return NULL;
247         }
248
249         return jsobject;
250 }
251
252 bool JSContactPhoneNumber::hasInstance(JSContextRef context,
253                 JSObjectRef constructor,
254                 JSValueRef possibleInstance,
255                 JSValueRef* exception)
256 {
257         return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
258 }
259
260 JSValueRef JSContactPhoneNumber::getNumber(JSContextRef context,
261                 JSObjectRef object,
262                 JSStringRef propertyName,
263                 JSValueRef* exception)
264 {
265         Try
266         {
267                 ContactConverterFactory::ConverterType converter =
268                                 ContactConverterFactory::getConverter(context);
269                 ContactPhoneNumberPtr contactPhoneNumber = getPrivData(object);
270                 return converter->toJSValueRef(contactPhoneNumber->getNumber());
271         }
272         Catch(WrtDeviceApis::Commons::Exception)
273         {
274                 LogWarning("trying to get incorrect value");
275         }
276         return JSValueMakeUndefined(context);
277 }
278
279 bool JSContactPhoneNumber::setNumber(JSContextRef context,
280                 JSObjectRef object,
281                 JSStringRef propertyName,
282                 JSValueRef value,
283                 JSValueRef* exception)
284 {
285         Try
286         {
287                 ContactPhoneNumberPtr contactPhoneNumber = getPrivData(object);
288                 ContactConverterFactory::ConverterType converter =
289                                 ContactConverterFactory::getConverter(context);
290                 contactPhoneNumber->setNumber(converter->toString(value));
291                 return true;
292         }
293         Catch(WrtDeviceApis::Commons::Exception)
294         {
295                 LogWarning("trying to set incorrect value");
296         }
297         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
298         return false;
299 }
300
301
302 JSValueRef JSContactPhoneNumber::getIsDefault(JSContextRef context,
303                 JSObjectRef object,
304                 JSStringRef propertyName,
305                 JSValueRef* exception)
306 {
307         Try
308         {
309                 ContactConverterFactory::ConverterType converter =
310                                 ContactConverterFactory::getConverter(context);
311                 ContactPhoneNumberPtr contactPhoneNumber = getPrivData(object);
312                 return converter->toJSValueRef(contactPhoneNumber->getIsDefault());
313         }
314         Catch(WrtDeviceApis::Commons::Exception)
315         {
316                 LogWarning("trying to get incorrect value");
317         }
318         return JSValueMakeUndefined(context);
319 }
320
321 bool JSContactPhoneNumber::setIsDefault(JSContextRef context,
322                 JSObjectRef object,
323                 JSStringRef propertyName,
324                 JSValueRef value,
325                 JSValueRef* exception)
326 {
327         Try
328         {
329                 ContactPhoneNumberPtr contactPhoneNumber = getPrivData(object);
330                 ContactConverterFactory::ConverterType converter =
331                                 ContactConverterFactory::getConverter(context);
332                 BasicValidator validator =
333                                 BasicValidatorFactory::getValidator(context, exception);
334                 contactPhoneNumber->setIsDefault(converter->toBool(value));
335                 return true;
336         }
337         Catch(WrtDeviceApis::Commons::Exception)
338         {
339                 LogWarning("trying to set incorrect value");
340         }
341         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
342         return false;
343 }
344
345
346 JSValueRef JSContactPhoneNumber::getTypes(JSContextRef context,
347                 JSObjectRef object,
348                 JSStringRef propertyName,
349                 JSValueRef* exception)
350 {
351         Try
352         {
353                 JSContactPhoneNumberPriv *priv = static_cast<JSContactPhoneNumberPriv*>(JSObjectGetPrivate(object));
354                 if (!priv) {
355                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
356                 }
357                 JSContextRef gContext = priv->getContext();
358                 ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
359                 ContactPhoneNumberPtr contactPhoneNumber = getPrivData(object);
360
361                 if(contactPhoneNumber->IsTypesSetJSArray()){
362                         return contactPhoneNumber->getTypesJSObj();
363                 }else{
364                         JSValueRef tempJSValue = contactPhoneNumber->getTypesJSArray();
365                         tempJSValue = converter->toJSValueRef(contactPhoneNumber->getTypes());
366
367                         JSObjectRef convertedJSObject = contactPhoneNumber->getTypesJSObj();
368                         convertedJSObject = JSValueToObject( gContext, tempJSValue, NULL );
369                         contactPhoneNumber->setTypesJSArray(true, convertedJSObject);
370
371                         JSValueProtect(gContext, convertedJSObject);
372                         contactPhoneNumber->setContext(gContext);
373                         return tempJSValue;
374                 }
375         }
376         Catch(WrtDeviceApis::Commons::Exception)
377         {
378                 LogWarning("trying to get incorrect value");
379         }
380         return JSValueMakeUndefined(context);
381 }
382
383 bool JSContactPhoneNumber::setTypes(JSContextRef context,
384                 JSObjectRef object,
385                 JSStringRef propertyName,
386                 JSValueRef value,
387                 JSValueRef* exception)
388 {
389         Try
390         {
391                 ContactPhoneNumberPtr contactPhoneNumber = getPrivData(object);
392                 ContactConverterFactory::ConverterType converter =
393                                 ContactConverterFactory::getConverter(context);
394
395                 contactPhoneNumber->setTypes(converter->toContactPhoneNumberTypeArray(value));
396
397                 return true;
398         }
399         Catch(WrtDeviceApis::Commons::Exception)
400         {
401                 LogWarning("trying to set incorrect value");
402         }
403         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
404         return false;
405 }
406
407 } // Contact
408 } // DeviceAPI