92b9c11d06780bf80ed0a9a6195dfd1cb35402c4
[framework/web/wrt-plugins-tizen.git] / src / Contact / JSContact.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        JSContact.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @brief       Implementation of the JSContact 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 <SecurityExceptions.h>
31 #include "ContactFactory.h"
32 #include "plugin_config.h"
33 #include "ContactConverter.h"
34 #include "JSContact.h"
35 #include "Contact.h"
36
37 #define FILTER_CLASS_NAME "Contact"
38
39 #define CONTACT_ATTR_ID             "id"
40 #define CONTACT_ATTR_ADDRESSBOOK_ID "addressBookId"
41 #define CONTACT_ATTR_PERSON_ID      "personId"
42 #define CONTACT_ATTR_LAST_UPDATED   "lastUpdated"
43 #define CONTACT_ATTR_IS_FAVORITE    "isFavorite"
44 #define CONTACT_ATTR_NAME           "name"
45 #define CONTACT_ATTR_ADDRESSES      "addresses"
46 #define CONTACT_ATTR_PHOTO_URI      "photoURI"
47 #define CONTACT_ATTR_PHONE_NUMBERS  "phoneNumbers"
48 #define CONTACT_ATTR_EMAILS         "emails"
49 #define CONTACT_ATTR_BIRTHDAY       "birthday"
50 #define CONTACT_ATTR_ANNIVERSARIES  "anniversaries"
51 #define CONTACT_ATTR_ORGANIZATIONS  "organizations"
52 #define CONTACT_ATTR_NOTES          "notes"
53 #define CONTACT_ATTR_URLS           "urls"
54 #define CONTACT_ATTR_LAST_UPDATED   "lastUpdated"
55 #define CONTACT_ATTR_RINGTONE_URI   "ringtoneURI"
56 #define CONTACT_ATTR_GROUP_IDS      "groupIds"
57 #define CONTACT_FUNC_CONVERT_TO_STRING          "convertToString"
58 #define CONTACT_FUNC_CLONE                                      "clone"
59
60 namespace DeviceAPI {
61 namespace Contact {
62
63 using namespace DeviceAPI::Common;
64 using namespace WrtDeviceApis::Commons;
65 using namespace WrtDeviceApis::CommonsJavaScript;
66
67 JSClassDefinition JSContact::m_classInfo =
68 {
69         0,
70         kJSClassAttributeNone,
71         FILTER_CLASS_NAME,
72         NULL,
73         m_property,
74         m_functions,
75         Initialize,
76         Finalize,
77         NULL, //hasProperty,
78         NULL, //GetProperty,
79         NULL, //SetProperty,
80         NULL, //DeleteProperty,
81         NULL, //getPropertyNames,
82         NULL, //CallAsFunction,
83         constructor, //CallAsConstructor,
84         hasInstance, //HasInstance,
85         NULL, //ConvertToType,
86 };
87
88 JSStaticValue JSContact::m_property[] = {
89         { CONTACT_ATTR_ID, getId, NULL, kJSPropertyAttributeReadOnly },
90         { CONTACT_ATTR_ADDRESSBOOK_ID, getAddressBookId, NULL, kJSPropertyAttributeReadOnly },
91         { CONTACT_ATTR_PERSON_ID, getPersonId, NULL, kJSPropertyAttributeReadOnly },
92         { CONTACT_ATTR_LAST_UPDATED, getLastUpdated, NULL, kJSPropertyAttributeReadOnly },
93         { CONTACT_ATTR_IS_FAVORITE, getIsFavorite, NULL, kJSPropertyAttributeReadOnly },
94         { CONTACT_ATTR_NAME, getName, setName, kJSPropertyAttributeNone },
95         { CONTACT_ATTR_ADDRESSES, getAddresses, setAddresses, kJSPropertyAttributeNone },
96         { CONTACT_ATTR_PHOTO_URI, getPhotoURI, setPhotoURI, kJSPropertyAttributeNone },
97         { CONTACT_ATTR_PHONE_NUMBERS, getPhoneNumbers, setPhoneNumbers, kJSPropertyAttributeNone },
98         { CONTACT_ATTR_EMAILS, getEmails, setEmails, kJSPropertyAttributeNone },
99         { CONTACT_ATTR_BIRTHDAY, getBirthday, setBirthday, kJSPropertyAttributeNone },
100         { CONTACT_ATTR_ANNIVERSARIES, getAnniversaries, setAnniversaries, kJSPropertyAttributeNone },
101         { CONTACT_ATTR_ORGANIZATIONS, getOrganizations, setOrganizations, kJSPropertyAttributeNone },
102         { CONTACT_ATTR_NOTES, getNotes, setNotes, kJSPropertyAttributeNone },
103         { CONTACT_ATTR_URLS, getUrls, setUrls, kJSPropertyAttributeNone },
104         { CONTACT_ATTR_RINGTONE_URI, getRingtoneURI, setRingtoneURI, kJSPropertyAttributeNone },
105         { CONTACT_ATTR_GROUP_IDS, getGroupIds, setGroupIds, kJSPropertyAttributeNone },
106         { 0, 0, 0, 0 }
107 };
108
109 JSStaticFunction JSContact::m_functions[] =
110 {
111         { CONTACT_FUNC_CONVERT_TO_STRING, convertToString, kJSPropertyAttributeNone },
112         { CONTACT_FUNC_CLONE, clone, kJSPropertyAttributeNone },
113         { 0, 0, 0 }
114 };
115
116 JSClassRef JSContact::m_classRef = JSClassCreate(&m_classInfo);
117
118 JSClassRef JSContact::getClassRef() {
119         if (!m_classRef) {
120                 m_classRef = JSClassCreate(&m_classInfo);
121         }
122         return m_classRef;
123 }
124
125 bool JSContact::isObjectOfClass(JSContextRef context, JSValueRef value)
126 {
127         return JSValueIsObjectOfClass(context, value, getClassRef());
128 }
129
130 ContactPtr JSContact::getContact(JSContextRef context, JSValueRef value)
131 {
132         if (!isObjectOfClass(context, value)) {
133                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
134         }
135         JSObjectRef object = JSValueToObject(context, value, NULL);
136         if (!object) {
137                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
138         }
139         JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
140         if (!priv) {
141                 Throw(WrtDeviceApis::Commons::NullPointerException);
142         }
143         return priv->getObject();
144 }
145
146 void JSContact::Initialize(JSContextRef context, JSObjectRef object)
147 {
148         if (!JSObjectGetPrivate(object))
149         {
150                 ContactPtr contact = ContactFactory::getInstance().createContact();
151                 JSContactPriv *priv = new JSContactPriv(context, ContactPtr(contact));
152                 if (!JSObjectSetPrivate(object, priv)) {
153                         delete priv;
154                 }
155         }
156 }
157
158 void JSContact::Finalize(JSObjectRef object)
159 {
160         JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
161
162         if (priv != NULL)
163                 delete (priv);
164 }
165
166 JSObjectRef JSContact::createJSObject(JSContextRef context, ContactPtr contact)
167 {
168         JSContactPriv *priv = new JSContactPriv(context, contact);
169         JSObjectRef jsObjectRef = JSObjectMake(context, getClassRef(), static_cast<void*>(priv));
170         if (NULL == jsObjectRef) {
171                 LogError("object creation error");
172                 return NULL;
173         }
174         return jsObjectRef;
175 }
176
177 ContactPtr JSContact::getPrivData(JSObjectRef object)
178 {
179         JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
180         if (!priv) {
181                 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
182         }
183         ContactPtr result = priv->getObject();
184         if (!result) {
185                 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null.");
186         }
187         return result;
188 }
189
190 JSObjectRef JSContact::constructor(JSContextRef context,
191                 JSObjectRef constructor,
192                 size_t argumentCount,
193                 const JSValueRef arguments[],
194                 JSValueRef* exception)
195 {
196         LogDebug("entered");
197
198         bool jsNoParam = false;
199         bool js1stParamIsObject = false;
200         bool js1stParamIsString = false;
201
202         JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(constructor));
203         if (!priv) {
204                 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
205         }
206         JSContextRef gContext = priv->getContext();
207
208         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
209         if (argumentCount == 0)
210         {
211                 jsNoParam = true;
212         }
213         else
214         {
215                 if (JSValueIsNull(gContext, arguments[0]) || JSValueIsUndefined(gContext, arguments[0]))
216                         jsNoParam = true;
217                 else if (JSValueIsObject(gContext, arguments[0]))
218                         js1stParamIsObject = true;
219                 else if (JSValueIsString(gContext, arguments[0]))
220                         js1stParamIsString = true;
221                 else
222                 {
223                         LogError("Argument type mismatch : 1nd argument must be ContactInit object or string");
224                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "2nd argument must be 'ContactTextFormat'");
225                         return NULL;
226                 }
227         }
228
229         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
230
231         ContactPtr contact(NULL);
232         if(js1stParamIsObject)
233         {
234                 Try {
235                         contact = converter->toContactFromInit(arguments[0]);
236
237                 } Catch(ConversionException) {
238                         LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
239                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "1st argument must be 'ContactInit object'");
240                         return NULL;
241                 } Catch(Exception) {
242                         LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
243                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Internal error");
244                         return NULL;
245                 }
246         }
247         else if(js1stParamIsString)
248         {
249                 Try {
250                         std::string stringRepresentation;       // vCard string
251
252                         stringRepresentation = converter->toString(arguments[0]);
253
254                         contact = ContactFactory::getInstance().createContact();
255                         contact->setContactFromString(stringRepresentation);
256
257                 } Catch(ConversionException) {
258                         LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
259                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "2nd argument must be 'ContactTextFormat'");
260                         return NULL;
261                 } Catch(InvalidArgumentException) {
262                         LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
263                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "1st argument must be vCard string");
264                         return NULL;
265                 } Catch(UnsupportedException) {
266                         LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
267                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::NOT_SUPPORTED_ERROR, "Only support vCard 3.0");
268                         return NULL;
269                 } Catch(Exception) {
270                         LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
271                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Internal error");
272                         return NULL;
273                 }
274         }
275         else
276         {
277                 Try {
278                         contact = ContactFactory::getInstance().createContact();
279                 } Catch(Exception) {
280                         LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
281                         *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Internal error");
282                         return NULL;
283                 }
284         }
285
286         JSObjectRef jsobject;
287
288         Try {
289                 jsobject = createJSObject(gContext, contact);
290         } Catch(Exception) {
291                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
292                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Internal error");
293                 return NULL;
294         }
295
296         return jsobject;
297 }
298
299 bool JSContact::hasInstance(JSContextRef context,
300                 JSObjectRef constructor,
301                 JSValueRef possibleInstance,
302                 JSValueRef* exception)
303 {
304         return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
305 }
306
307 JSValueRef JSContact::getId(JSContextRef context,
308                 JSObjectRef object,
309                 JSStringRef propertyName,
310                 JSValueRef* exception)
311 {
312         Try
313         {
314                 ContactConverterFactory::ConverterType converter =
315                                 ContactConverterFactory::getConverter(context);
316                 ContactPtr contact = getPrivData(object);
317                 if(!contact->getIdIsSet())
318                         return JSValueMakeNull(context);
319                 else
320                         return converter->toJSValueRef(contact->getId());
321         }
322         Catch(WrtDeviceApis::Commons::Exception)
323         {
324                 LogWarning("trying to get incorrect value");
325         }
326         return JSValueMakeUndefined(context);
327 }
328
329 JSValueRef JSContact::getAddressBookId(JSContextRef context,
330                 JSObjectRef object,
331                 JSStringRef propertyName,
332                 JSValueRef* exception)
333 {
334         Try
335         {
336                 ContactConverterFactory::ConverterType converter =
337                                 ContactConverterFactory::getConverter(context);
338                 ContactPtr contact = getPrivData(object);
339                 if(!contact->getAddressBookIdIsSet())
340                         return JSValueMakeNull(context);
341                 else
342                         return converter->toJSValueRef(contact->getAddressBookId());
343         }
344         Catch(WrtDeviceApis::Commons::Exception)
345         {
346                 LogWarning("trying to get incorrect value");
347         }
348         return JSValueMakeUndefined(context);
349 }
350
351 JSValueRef JSContact::getPersonId(JSContextRef context,
352                 JSObjectRef object,
353                 JSStringRef propertyName,
354                 JSValueRef* exception)
355 {
356         Try
357         {
358                 ContactConverterFactory::ConverterType converter =
359                                 ContactConverterFactory::getConverter(context);
360                 ContactPtr contact = getPrivData(object);
361                 if(!contact->getPersonIdIsSet())
362                         return JSValueMakeNull(context);
363                 else
364                         return converter->toJSValueRef(contact->getPersonId());
365         }
366         Catch(WrtDeviceApis::Commons::Exception)
367         {
368                 LogWarning("trying to get incorrect value");
369         }
370         return JSValueMakeUndefined(context);
371 }
372
373 JSValueRef JSContact::getLastUpdated(JSContextRef context,
374                 JSObjectRef object,
375                 JSStringRef propertyName,
376                 JSValueRef* exception)
377 {
378         Try
379         {
380                 ContactConverterFactory::ConverterType converter =
381                                 ContactConverterFactory::getConverter(context);
382                 ContactPtr contact = getPrivData(object);
383                 if(!contact->getLastUpdatedIsSet())
384                         return JSValueMakeNull(context);
385                 else
386                         return converter->toJSValueRef(contact->getLastUpdated());
387         }
388         Catch(WrtDeviceApis::Commons::Exception)
389         {
390                 LogWarning("trying to get incorrect value");
391         }
392
393         return JSValueMakeUndefined(context);
394 }
395
396 JSValueRef JSContact::getIsFavorite(JSContextRef context,
397                 JSObjectRef object,
398                 JSStringRef propertyName,
399                 JSValueRef* exception)
400 {
401         Try
402         {
403                 ContactConverterFactory::ConverterType converter =
404                                 ContactConverterFactory::getConverter(context);
405                 ContactPtr contact = getPrivData(object);
406                 return converter->toJSValueRef(contact->getIsFavorite());
407         }
408         Catch(WrtDeviceApis::Commons::Exception)
409         {
410                 LogWarning("trying to get incorrect value");
411         }
412
413         return JSValueMakeUndefined(context);
414 }
415
416 JSValueRef JSContact::getName(JSContextRef context,
417                 JSObjectRef object,
418                 JSStringRef propertyName,
419                 JSValueRef* exception)
420 {
421         Try
422         {
423                 JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
424                 if (!priv) {
425                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
426                 }
427                 JSContextRef gContext = priv->getContext();
428
429                 ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
430                 ContactPtr contact = getPrivData(object);
431                 ContactNamePtr contactName = contact->getName();
432                 if(contactName == NULL)
433                         return JSValueMakeNull(context);
434                 else
435                         return converter->toJSValueRef(contactName);
436         }
437         Catch(WrtDeviceApis::Commons::Exception)
438         {
439                 LogWarning("trying to get incorrect value");
440         }
441
442         return JSValueMakeUndefined(context);
443 }
444
445 bool JSContact::setName(JSContextRef context,
446                 JSObjectRef object,
447                 JSStringRef propertyName,
448                 JSValueRef value,
449                 JSValueRef* exception)
450 {
451         Try
452         {
453                 ContactPtr contact = getPrivData(object);
454                 ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
455                 BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
456                 if(validator->isNullOrUndefined(value))
457                         contact->unsetName();
458                 else
459                         contact->setName(converter->toContactName(value));
460                 return true;
461         }
462         Catch(WrtDeviceApis::Commons::Exception)
463         {
464                 LogWarning("trying to set incorrect value");
465         }
466
467         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
468         return false;
469 }
470
471 JSValueRef JSContact::getAddresses(JSContextRef context,
472                 JSObjectRef object,
473                 JSStringRef propertyName,
474                 JSValueRef* exception)
475 {
476         Try
477         {
478                 JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
479                 if (!priv) {
480                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
481                 }
482                 JSContextRef gContext = priv->getContext();
483                 ContactConverterFactory::ConverterType converter =
484                                 ContactConverterFactory::getConverter(gContext);
485                 ContactPtr contact = getPrivData(object);
486                 return converter->toJSValueRef(contact->getAddresses());
487         }
488         Catch(WrtDeviceApis::Commons::Exception)
489         {
490                 LogWarning("trying to get incorrect value");
491         }
492
493         return JSValueMakeUndefined(context);
494 }
495
496 bool JSContact::setAddresses(JSContextRef context,
497                 JSObjectRef object,
498                 JSStringRef propertyName,
499                 JSValueRef value,
500                 JSValueRef* exception)
501 {
502         Try
503         {
504                 ContactPtr contact = getPrivData(object);
505                 ContactConverterFactory::ConverterType converter =
506                                 ContactConverterFactory::getConverter(context);
507                 contact->setAddresses(converter->toContactAddressArray(value));
508                 return true;
509         }
510         Catch(WrtDeviceApis::Commons::Exception)
511         {
512                 LogWarning("trying to set incorrect value");
513         }
514
515         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
516         return false;
517 }
518
519 JSValueRef JSContact::getPhotoURI(JSContextRef context,
520                 JSObjectRef object,
521                 JSStringRef propertyName,
522                 JSValueRef* exception)
523 {
524         Try
525         {
526                 ContactConverterFactory::ConverterType converter =
527                                 ContactConverterFactory::getConverter(context);
528                 ContactPtr contact = getPrivData(object);
529                 if(!contact->getPhotoURIIsSet())
530                         return JSValueMakeNull(context);
531                 else
532                         return converter->toJSValueRef(contact->getPhotoURI());
533         }
534         Catch(WrtDeviceApis::Commons::Exception)
535         {
536                 LogWarning("trying to get incorrect value");
537         }
538
539         return JSValueMakeUndefined(context);
540 }
541
542 bool JSContact::setPhotoURI(JSContextRef context,
543                 JSObjectRef object,
544                 JSStringRef propertyName,
545                 JSValueRef value,
546                 JSValueRef* exception)
547 {
548         Try
549         {
550                 ContactPtr contact = getPrivData(object);
551                 ContactConverterFactory::ConverterType converter =
552                                 ContactConverterFactory::getConverter(context);
553                 BasicValidator validator =
554                                 BasicValidatorFactory::getValidator(context, exception);
555                 if(validator->isNullOrUndefined(value))
556                         contact->unsetPhotoURI();
557                 else
558                         contact->setPhotoURI(converter->toString(value));
559                 return true;
560         }
561         Catch(WrtDeviceApis::Commons::Exception)
562         {
563                 LogWarning("trying to set incorrect value");
564         }
565
566         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
567         return false;
568 }
569
570 JSValueRef JSContact::getPhoneNumbers(JSContextRef context,
571                 JSObjectRef object,
572                 JSStringRef propertyName,
573                 JSValueRef* exception)
574 {
575         Try
576         {
577                 JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
578                 if (!priv) {
579                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
580                 }
581                 JSContextRef gContext = priv->getContext();
582                 ContactConverterFactory::ConverterType converter =
583                                 ContactConverterFactory::getConverter(gContext);
584                 ContactPtr contact = getPrivData(object);
585                 return converter->toJSValueRef(contact->getPhoneNumbers());
586         }
587         Catch(WrtDeviceApis::Commons::Exception)
588         {
589                 LogWarning("trying to get incorrect value");
590         }
591
592         return JSValueMakeUndefined(context);
593 }
594
595 bool JSContact::setPhoneNumbers(JSContextRef context,
596                 JSObjectRef object,
597                 JSStringRef propertyName,
598                 JSValueRef value,
599                 JSValueRef* exception)
600 {
601         Try
602         {
603                 ContactPtr contact = getPrivData(object);
604                 ContactConverterFactory::ConverterType converter =
605                                 ContactConverterFactory::getConverter(context);
606                 contact->setPhoneNumbers(
607                                 converter->toContactPhoneNumberArray(value));
608                 return true;
609         }
610         Catch(WrtDeviceApis::Commons::Exception)
611         {
612                 LogWarning("trying to set incorrect value");
613         }
614
615         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
616         return false;
617 }
618
619 JSValueRef JSContact::getEmails(JSContextRef context,
620                 JSObjectRef object,
621                 JSStringRef propertyName,
622                 JSValueRef* exception)
623 {
624         Try
625         {
626                 JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
627                 if (!priv) {
628                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
629                 }
630                 JSContextRef gContext = priv->getContext();
631
632                 ContactConverterFactory::ConverterType converter =
633                                 ContactConverterFactory::getConverter(gContext);
634                 ContactPtr contact = getPrivData(object);
635                 return converter->toJSValueRef(contact->getEmails());
636         }
637         Catch(WrtDeviceApis::Commons::Exception)
638         {
639                 LogWarning("trying to get incorrect value");
640         }
641
642         return JSValueMakeUndefined(context);
643 }
644
645 bool JSContact::setEmails(JSContextRef context,
646                 JSObjectRef object,
647                 JSStringRef propertyName,
648                 JSValueRef value,
649                 JSValueRef* exception)
650 {
651         Try
652         {
653                 ContactPtr contact = getPrivData(object);
654                 ContactConverterFactory::ConverterType converter =
655                                 ContactConverterFactory::getConverter(context);
656                 contact->setEmails(converter->toContactEmailAddressArray(value));
657                 return true;
658         }
659         Catch(WrtDeviceApis::Commons::Exception)
660         {
661                 LogWarning("trying to set incorrect value");
662         }
663
664         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
665         return false;
666 }
667
668 JSValueRef JSContact::getBirthday(JSContextRef context,
669                 JSObjectRef object,
670                 JSStringRef propertyName,
671                 JSValueRef* exception)
672 {
673         Try
674         {
675                 ContactConverterFactory::ConverterType converter =
676                                 ContactConverterFactory::getConverter(context);
677                 ContactPtr contact = getPrivData(object);
678                 if(!contact->getBirthdayIsSet())
679                         return JSValueMakeNull(context);
680                 else
681                         return converter->toJSValueRef(contact->getBirthday());
682         }
683         Catch(WrtDeviceApis::Commons::Exception)
684         {
685                 LogWarning("trying to get incorrect value");
686         }
687
688         return JSValueMakeUndefined(context);
689 }
690
691 bool JSContact::setBirthday(JSContextRef context,
692                 JSObjectRef object,
693                 JSStringRef propertyName,
694                 JSValueRef value,
695                 JSValueRef* exception)
696 {
697         Try
698         {
699                 ContactPtr contact = getPrivData(object);
700                 ContactConverterFactory::ConverterType converter =
701                                 ContactConverterFactory::getConverter(context);
702                 BasicValidator validator =
703                                 BasicValidatorFactory::getValidator(context, exception);
704                 if(validator->isNullOrUndefined(value))
705                         contact->unsetBirthday();
706                 else
707                         contact->setBirthday(converter->toDateTm(value));
708                 return true;
709         }
710         Catch(WrtDeviceApis::Commons::Exception)
711         {
712                 LogWarning("trying to set incorrect value");
713         }
714
715         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
716         return false;
717 }
718
719 JSValueRef JSContact::getAnniversaries(JSContextRef context,
720                 JSObjectRef object,
721                 JSStringRef propertyName,
722                 JSValueRef* exception)
723 {
724         Try
725         {
726                 ContactConverterFactory::ConverterType converter =
727                                 ContactConverterFactory::getConverter(context);
728                 ContactPtr contact = getPrivData(object);
729                 return converter->toJSValueRef(contact->getAnniversaries());
730         }
731         Catch(WrtDeviceApis::Commons::Exception)
732         {
733                 LogWarning("trying to get incorrect value");
734         }
735
736         return JSValueMakeUndefined(context);
737 }
738
739 bool JSContact::setAnniversaries(JSContextRef context,
740                 JSObjectRef object,
741                 JSStringRef propertyName,
742                 JSValueRef value,
743                 JSValueRef* exception)
744 {
745         Try
746         {
747                 ContactPtr contact = getPrivData(object);
748                 ContactConverterFactory::ConverterType converter =
749                                 ContactConverterFactory::getConverter(context);
750                 contact->setAnniversaries(
751                                 converter->toContactAnniversaryArray(value));
752                 return true;
753         }
754         Catch(WrtDeviceApis::Commons::Exception)
755         {
756                 LogWarning("trying to set incorrect value");
757         }
758
759         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
760         return false;
761 }
762
763 JSValueRef JSContact::getOrganizations(JSContextRef context,
764                 JSObjectRef object,
765                 JSStringRef propertyName,
766                 JSValueRef* exception)
767 {
768         Try
769         {
770                 ContactConverterFactory::ConverterType converter =
771                                 ContactConverterFactory::getConverter(context);
772                 ContactPtr contact = getPrivData(object);
773                 return converter->toJSValueRef(contact->getOrganizations());
774         }
775         Catch(WrtDeviceApis::Commons::Exception)
776         {
777                 LogWarning("trying to get incorrect value");
778         }
779
780         return JSValueMakeUndefined(context);
781 }
782
783 bool JSContact::setOrganizations(JSContextRef context,
784                 JSObjectRef object,
785                 JSStringRef propertyName,
786                 JSValueRef value,
787                 JSValueRef* exception)
788 {
789         Try
790         {
791                 ContactPtr contact = getPrivData(object);
792                 ContactConverterFactory::ConverterType converter =
793                                 ContactConverterFactory::getConverter(context);
794                 contact->setOrganizations(
795                                 converter->toContactOrganizationArray(value));
796                 return true;
797         }
798         Catch(WrtDeviceApis::Commons::Exception)
799         {
800                 LogWarning("trying to set incorrect value");
801         }
802
803         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
804         return false;
805 }
806
807 JSValueRef JSContact::getNotes(JSContextRef context,
808                 JSObjectRef object,
809                 JSStringRef propertyName,
810                 JSValueRef* exception)
811 {
812         Try
813         {
814                 JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
815                 if (!priv) {
816                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
817                 }
818                 JSContextRef gContext = priv->getContext();
819
820                 ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
821                 ContactPtr contact = getPrivData(object);
822
823                 DPL::SharedPtr<Contact> newContactT = DPL::StaticPointerCast<Contact>(contact);
824                 if(newContactT->notesJSObjIsSet()){
825                         return newContactT->getNotesJSObj();
826                 }else{
827                         JSValueRef tempJSValue = newContactT->getNotesJSValue();
828                         tempJSValue = converter->toJSValueRef(newContactT->getNotes());
829
830                         JSObjectRef convertedJSObject = newContactT->getNotesJSObj();
831                         convertedJSObject = JSValueToObject( gContext, tempJSValue, NULL );
832                         newContactT->setNotesJSObj(true, convertedJSObject);
833
834                         JSValueProtect(gContext, convertedJSObject);
835                         newContactT->setContext(gContext);
836                         return tempJSValue;
837                 }
838         }
839         Catch(WrtDeviceApis::Commons::Exception)
840         {
841                 LogWarning("trying to get incorrect value");
842         }
843
844         return JSValueMakeUndefined(context);
845 }
846
847 bool JSContact::setNotes(JSContextRef context,
848                 JSObjectRef object,
849                 JSStringRef propertyName,
850                 JSValueRef value,
851                 JSValueRef* exception)
852 {
853         Try
854         {
855                 ContactPtr contact = getPrivData(object);
856                 ContactConverterFactory::ConverterType converter =
857                                 ContactConverterFactory::getConverter(context);
858                 contact->setNotes(converter->toStringArray(value));
859                 return true;
860         }
861         Catch(WrtDeviceApis::Commons::Exception)
862         {
863                 LogWarning("trying to set incorrect value");
864         }
865
866         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
867         return false;
868 }
869
870 JSValueRef JSContact::getUrls(JSContextRef context,
871                 JSObjectRef object,
872                 JSStringRef propertyName,
873                 JSValueRef* exception)
874 {
875         Try
876         {
877                 ContactConverterFactory::ConverterType converter =
878                                 ContactConverterFactory::getConverter(context);
879                 ContactPtr contact = getPrivData(object);
880                 return converter->toJSValueRef(contact->getUrls());
881         }
882         Catch(WrtDeviceApis::Commons::Exception)
883         {
884                 LogWarning("trying to get incorrect value");
885         }
886
887         return JSValueMakeUndefined(context);
888 }
889
890 bool JSContact::setUrls(JSContextRef context,
891                 JSObjectRef object,
892                 JSStringRef propertyName,
893                 JSValueRef value,
894                 JSValueRef* exception)
895 {
896         Try
897         {
898                 ContactPtr contact = getPrivData(object);
899                 ContactConverterFactory::ConverterType converter =
900                                 ContactConverterFactory::getConverter(context);
901                 contact->setUrls(converter->toContactWebSiteArray(value));
902                 return true;
903         }
904         Catch(WrtDeviceApis::Commons::Exception)
905         {
906                 LogWarning("trying to set incorrect value");
907         }
908
909         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
910         return false;
911 }
912
913 JSValueRef JSContact::getRingtoneURI(JSContextRef context,
914                 JSObjectRef object,
915                 JSStringRef propertyName,
916                 JSValueRef* exception)
917 {
918         Try
919         {
920                 ContactConverterFactory::ConverterType converter =
921                                 ContactConverterFactory::getConverter(context);
922                 ContactPtr contact = getPrivData(object);
923                 if(!contact->getRingtoneURIIsSet())
924                         return JSValueMakeNull(context);
925                 else
926                         return converter->toJSValueRef(contact->getRingtoneURI());
927         }
928         Catch(WrtDeviceApis::Commons::Exception)
929         {
930                 LogWarning("trying to get incorrect value");
931         }
932
933         return JSValueMakeUndefined(context);
934 }
935
936 bool JSContact::setRingtoneURI(JSContextRef context,
937                 JSObjectRef object,
938                 JSStringRef propertyName,
939                 JSValueRef value,
940                 JSValueRef* exception)
941 {
942         Try
943         {
944                 ContactPtr contact = getPrivData(object);
945                 ContactConverterFactory::ConverterType converter =
946                                 ContactConverterFactory::getConverter(context);
947                 BasicValidator validator =
948                                 BasicValidatorFactory::getValidator(context, exception);
949                 if(validator->isNullOrUndefined(value))
950                         contact->unsetRingtoneURI();
951                 else
952                         contact->setRingtoneURI(converter->toString(value));
953                 return true;
954         }
955         Catch(WrtDeviceApis::Commons::Exception)
956         {
957                 LogWarning("trying to set incorrect value");
958         }
959
960         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
961         return false;
962 }
963
964 JSValueRef JSContact::getGroupIds(JSContextRef context,
965                 JSObjectRef object,
966                 JSStringRef propertyName,
967                 JSValueRef* exception)
968 {
969         Try
970         {
971                 JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(object));
972                 if (!priv) {
973                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
974                 }
975                 JSContextRef gContext = priv->getContext();
976
977                 ContactConverterFactory::ConverterType converter =
978                                 ContactConverterFactory::getConverter(gContext);
979                 ContactPtr contact = getPrivData(object);
980                 DPL::SharedPtr<Contact> newContactT = DPL::StaticPointerCast<Contact>(contact);
981
982                 if(newContactT->groupIdsJSObjIsSet()){
983                         return newContactT->getGroupIdsJSObj();
984                 }else{
985                         JSValueRef tempJSValue = newContactT->getGroupIdsJSValue();
986                         tempJSValue = converter->toJSValueRef(newContactT->getGroupIds());
987
988                         JSObjectRef convertedJSObject = newContactT->getGroupIdsJSObj();
989                         convertedJSObject = JSValueToObject( gContext, tempJSValue, NULL );
990                         newContactT->setGroupIdsJSObj(true, convertedJSObject);
991
992                         JSValueProtect(gContext, convertedJSObject);
993                         newContactT->setContext(gContext);
994                         return tempJSValue;
995                 }
996         }
997         Catch(WrtDeviceApis::Commons::Exception)
998         {
999                 LogWarning("trying to get incorrect value");
1000         }
1001
1002         return JSValueMakeUndefined(context);
1003 }
1004
1005 bool JSContact::setGroupIds(JSContextRef context,
1006                 JSObjectRef object,
1007                 JSStringRef propertyName,
1008                 JSValueRef value,
1009                 JSValueRef* exception)
1010 {
1011         Try
1012         {
1013                 ContactPtr contact = getPrivData(object);
1014                 ContactConverterFactory::ConverterType converter =
1015                                 ContactConverterFactory::getConverter(context);
1016                 contact->setGroupIds(converter->toStringArray(value));
1017                 return true;
1018         }
1019         Catch(WrtDeviceApis::Commons::Exception)
1020         {
1021                 LogWarning("trying to set incorrect value");
1022         }
1023
1024         JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
1025         return false;
1026 }
1027
1028 JSValueRef JSContact::convertToString(JSContextRef context,
1029                 JSObjectRef object,
1030                 JSObjectRef thisObject,
1031                 size_t argumentCount,
1032                 const JSValueRef arguments[],
1033                 JSValueRef* exception)
1034 {
1035         LogDebug("entered");
1036         ContactPtr contact(NULL);
1037
1038         Try     {
1039                 contact = getPrivData(thisObject);
1040                 if (contact == NULL) {
1041                         ThrowMsg(InvalidArgumentException, "No private object.");
1042                 }
1043         } Catch(Exception) {
1044                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
1045                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
1046         }
1047
1048 //      AceSecurityStatus status = CONTACT_CHECK_ACCESS(
1049 //      CONTACT_FUNCTION_API_CONVERT_TO_STRING);
1050 //      TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1051
1052         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
1053         Try {
1054                 if (argumentCount >= 1 &&
1055                                 ( !JSValueIsUndefined(context, arguments[0] ) &&
1056                                 ( !JSValueIsNull(context, arguments[0]) ) &&
1057                                 ( !JSValueIsString(context, arguments[0] )) ))
1058                         ThrowMsg(ConversionException, "1st argument must be 'ContactTextFormat string'");
1059         } Catch (Exception) {
1060                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
1061                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "1st argument must be 'ContactTextFormat string'");
1062         }
1063
1064         std::string format;
1065
1066         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1067         Try     {
1068                 if(argumentCount >= 1)
1069                         format = converter->toString(arguments[0]);
1070         } Catch(Exception) {
1071                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
1072                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "1st argument must be 'ContactTextFormat string'");
1073         }
1074
1075         std::string vCard;
1076         Try {
1077                 vCard = contact->convertToString(format);
1078         } Catch(ConversionException) {
1079                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
1080                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "1st argument must be 'ContactTextFormat string'");
1081         } Catch(UnsupportedException) {
1082                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
1083                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, "Only support vCard 3.0");
1084         } Catch(Exception) {
1085                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
1086                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1087         }
1088
1089         JSValueRef result;
1090         Try {
1091                 result = converter->toJSValueRef(vCard);
1092         } Catch(Exception) {
1093                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
1094                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1095         }
1096
1097         return result;
1098 }
1099
1100 JSValueRef JSContact::clone(JSContextRef context,
1101                 JSObjectRef object,
1102                 JSObjectRef thisObject,
1103                 size_t argumentCount,
1104                 const JSValueRef arguments[],
1105                 JSValueRef* exception)
1106 {
1107         LogDebug("entered");
1108         ContactPtr contact(NULL);
1109
1110         Try     {
1111                 contact = getPrivData(thisObject);
1112                 if (contact == NULL) {
1113                         ThrowMsg(InvalidArgumentException, "No private object.");
1114                 }
1115         } Catch(Exception) {
1116                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
1117                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
1118         }
1119
1120 //      AceSecurityStatus status = CONTACT_CHECK_ACCESS(
1121 //      CONTACT_FUNCTION_API_CONVERT_TO_STRING);
1122 //      TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1123
1124         ContactPtr clonedContact(NULL);
1125         Try {
1126                 clonedContact = contact->clone();
1127         } Catch(Exception) {
1128                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
1129                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1130         }
1131
1132         JSValueRef result;
1133         Try {
1134                 JSContactPriv *priv = static_cast<JSContactPriv*>(JSObjectGetPrivate(thisObject));
1135                 if (!priv) {
1136                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is null");
1137                 }
1138                 JSContextRef gContext = priv->getContext();
1139                 result = createJSObject(gContext, clonedContact);
1140         } Catch(Exception) {
1141                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
1142                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1143         }
1144
1145         return result;
1146 }
1147
1148 } // Contact
1149 } // DeviceAPI