Update change log and spec for wrt-plugins-tizen_0.4.49
[framework/web/wrt-plugins-tizen.git] / src / Contact / JSAddressBook.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        JSAddressBook.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @brief       Implementation of the JSAddressBook class
23  */
24
25 #include <CommonsJavaScript/Validator.h>
26 #include <CommonsJavaScript/Converter.h>
27 #include <CommonsJavaScript/JSCallbackManager.h>
28 #include <CommonsJavaScript/JSUtils.h>
29 #include <CommonsJavaScript/JSPendingOperation.h>
30 #include <SecurityExceptions.h>
31 #include <FilterConverter.h>
32 #include "ContactFactory.h"
33 #include "EventAddressBookAddBatch.h"
34 #include "EventAddressBookUpdateBatch.h"
35 #include "EventAddressBookRemoveBatch.h"
36 #include "EventAddressBookFind.h"
37 #include "EventAddressBookChangeListener.h"
38 #include "EventAddressBookRemoveBatch.h"
39 #include "plugin_config.h"
40 #include "JSAddressBook.h"
41 #include "JSContact.h"
42 #include "JSContactGroup.h"
43 #include "ContactConverter.h"
44 #include "AddressBookController.h"
45 #include "JSAddressBookChangeCallbackManager.h"
46 #include "ContactAsyncCallbackManager.h"
47 #include "ContactListenerManager.h"
48 #include "ContactFilterConverter.h"
49 #include <ArgumentValidator.h>
50 #include <JSWebAPIErrorFactory.h>
51 #include <JSUtil.h>
52 #include <TimeTracer.h>
53 #include <Logger.h>
54
55 using namespace std;
56
57 #define TIZEN_ADDRESS_BOOK_ID           "id"
58 #define TIZEN_ADDRESS_BOOK_NAME         "name"
59 #define TIZEN_ADDRESS_BOOK_READ_ONLY    "readOnly"
60 #define TIZEN_ADDRESS_BOOK_ACCOUNT_ID   "accountId"
61
62 #define TIZEN_ADDRESS_BOOK              "AddressBook"
63
64 namespace DeviceAPI {
65 namespace Contact {
66
67 using namespace DeviceAPI::Common;
68 using namespace DeviceAPI::Tizen;
69 using namespace WrtDeviceApis::Commons;
70 using namespace WrtDeviceApis::CommonsJavaScript;
71
72 JSClassRef JSAddressBook::m_jsClassRef = NULL;
73
74 JSClassDefinition JSAddressBook::m_classInfo = {
75         0,
76         kJSClassAttributeNone,
77         TIZEN_ADDRESS_BOOK,
78         0,
79         m_property,
80         m_function,
81         Initialize,
82         Finalize,
83         NULL, //HasProperty,
84         NULL, //GetProperty,
85         NULL, //SetProperty,
86         NULL, //DeleteProperty,
87         NULL, //GetPropertyNames,
88         NULL, //CallAsFunction,
89         NULL, //CallAsConstructor,
90         NULL, //HasInstance,
91         NULL, //ConvertToType,
92 };
93
94 JSStaticValue JSAddressBook::m_property[] = {
95         { TIZEN_ADDRESS_BOOK_ID, getId, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
96         { TIZEN_ADDRESS_BOOK_NAME, getName, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
97         { TIZEN_ADDRESS_BOOK_READ_ONLY, getReadOnly, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
98 //      { TIZEN_ADDRESS_BOOK_ACCOUNT_ID, getAccountId, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
99         { 0, 0, 0, 0 }
100 };
101
102 JSStaticFunction JSAddressBook::m_function[] = {
103         { "get", get, kJSPropertyAttributeNone },
104         { "add", add, kJSPropertyAttributeNone },
105         { "addBatch", addBatch, kJSPropertyAttributeNone },
106         { "update", update, kJSPropertyAttributeNone },
107         { "updateBatch", updateBatch, kJSPropertyAttributeNone },
108         { "remove", remove, kJSPropertyAttributeNone },
109         { "removeBatch", removeBatch, kJSPropertyAttributeNone },
110         { "find", find, kJSPropertyAttributeNone },
111         { "addChangeListener", addChangeListener, kJSPropertyAttributeNone },
112         { "removeChangeListener", removeChangeListener, kJSPropertyAttributeNone },
113         { "getGroup", getGroup, kJSPropertyAttributeNone },
114         { "addGroup", addGroup, kJSPropertyAttributeNone },
115         { "updateGroup", updateGroup, kJSPropertyAttributeNone },
116         { "removeGroup", removeGroup, kJSPropertyAttributeNone },
117         { "getGroups", getGroups, kJSPropertyAttributeNone },
118         { 0, 0, 0 }
119 };
120
121 const JSClassDefinition* JSAddressBook::getClassInfo()
122 {
123         return &m_classInfo;
124 }
125
126 const JSClassRef JSAddressBook::getClassRef()
127 {
128         LoggerI("entered");
129         if (!m_jsClassRef) {
130                 m_jsClassRef = JSClassCreate(&m_classInfo);
131         }
132         return m_jsClassRef;
133 }
134
135 void JSAddressBook::Initialize(JSContextRef context,
136                 JSObjectRef object)
137 {
138 //      AddressBookController *priv =
139 //              static_cast<AddressBookController*>(JSObjectGetPrivate(object));
140 }
141
142 void JSAddressBook::Finalize(JSObjectRef object)
143 {
144         AddressBookController *priv =
145                 static_cast<AddressBookController*>(JSObjectGetPrivate(object));
146
147         delete priv;
148 }
149
150 bool JSAddressBook::isObjectOfClass(JSContextRef context, JSValueRef value)
151 {
152         return JSValueIsObjectOfClass(context, value, getClassRef());
153 }
154
155 AddressBookPtr JSAddressBook::getAddressBook(JSContextRef context, JSValueRef value)
156 {
157         if (!isObjectOfClass(context, value)) {
158                 Throw(InvalidArgumentException);
159         }
160         JSObjectRef object = JSValueToObject(context, value, NULL);
161         if (!object) {
162                 Throw(InvalidArgumentException);
163         }
164         AddressBookController *priv = static_cast<AddressBookController*>(JSObjectGetPrivate(object));
165         if (!priv) {
166                 Throw(NullPointerException);
167         }
168         return priv->getObject();
169 }
170
171 AddressBookPtr JSAddressBook::getPrivData(JSObjectRef object)
172 {
173         AddressBookController *priv =
174                 static_cast<AddressBookController*>(JSObjectGetPrivate(object));
175         if (priv) {
176                 return priv->getObject();
177         }
178         Throw(NullPointerException);
179 }
180
181 JSValueRef JSAddressBook::getId(JSContextRef context,
182                 JSObjectRef object,
183                 JSStringRef propertyName,
184                 JSValueRef* exception)
185 {
186         Try
187         {
188                 ContactConverterFactory::ConverterType converter =
189                                 ContactConverterFactory::getConverter(context);
190                 AddressBookPtr addressBook = getPrivData(object);
191                 string id = addressBook->getId();
192                 if(id != "")
193                         return converter->toJSValueRef(id);
194                 else
195                         return JSValueMakeNull(context);
196         }
197         Catch(WrtDeviceApis::Commons::Exception)
198         {
199                 LoggerW("trying to get incorrect value");
200         }
201         return JSValueMakeUndefined(context);
202 }
203
204 JSValueRef JSAddressBook::getName(JSContextRef context,
205                 JSObjectRef object,
206                 JSStringRef propertyName,
207                 JSValueRef* exception)
208 {
209         Try
210         {
211                 ContactConverterFactory::ConverterType converter =
212                                 ContactConverterFactory::getConverter(context);
213                 AddressBookPtr addressBook = getPrivData(object);
214                 return converter->toJSValueRef(addressBook->getName());
215         }
216         Catch(WrtDeviceApis::Commons::Exception)
217         {
218                 LoggerW("trying to get incorrect value");
219         }
220
221         return JSValueMakeUndefined(context);
222 }
223
224 JSValueRef JSAddressBook::getReadOnly(JSContextRef context,
225                 JSObjectRef object,
226                 JSStringRef propertyName,
227                 JSValueRef* exception)
228 {
229         Try
230         {
231                 ContactConverterFactory::ConverterType converter =
232                                 ContactConverterFactory::getConverter(context);
233                 AddressBookPtr addressBook = getPrivData(object);
234                 return converter->toJSValueRef(addressBook->getReadOnly());
235         }
236         Catch(WrtDeviceApis::Commons::Exception)
237         {
238                 LoggerW("trying to get incorrect value");
239         }
240
241         return JSValueMakeUndefined(context);
242 }
243
244 JSValueRef JSAddressBook::getAccountId(JSContextRef context,
245                 JSObjectRef object,
246                 JSStringRef propertyName,
247                 JSValueRef* exception)
248 {
249         Try
250         {
251                 ContactConverterFactory::ConverterType converter =
252                                 ContactConverterFactory::getConverter(context);
253                 AddressBookPtr addressBook = getPrivData(object);
254                 string accountId = addressBook->getAccountId();
255                 if(accountId != "")
256                         return converter->toJSValueRef(accountId);
257                 else
258                         return JSValueMakeNull(context);
259         }
260         Catch(WrtDeviceApis::Commons::Exception)
261         {
262                 LoggerW("trying to get incorrect value");
263         }
264         return JSValueMakeUndefined(context);
265 }
266
267 JSValueRef JSAddressBook::get(JSContextRef context,
268                 JSObjectRef object,
269                 JSObjectRef thisObject,
270                 size_t argumentCount,
271                 const JSValueRef arguments[],
272                 JSValueRef* exception)
273 {
274         LoggerD("entered");
275         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
276         AddressBookPtr addressBook;
277         AddressBookController *controller;
278         JSContextRef gContext;
279
280         Try     {
281                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
282                 if (!controller) {
283                         ThrowMsg(InvalidArgumentException, "No private object.");
284                 }
285                 addressBook = controller->getObject();
286                 gContext = controller->getContext();
287
288         } Catch(Exception) {
289                 LoggerE("No private object");
290                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
291         }
292
293         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_GET);
294         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
295
296         string id;
297
298         try     {
299                 ArgumentValidator validator(context, argumentCount, arguments);
300                 id = validator.toString(0, false);
301         } catch (const TypeMismatchException& err ) {
302                 return JSWebAPIErrorFactory::postException(context, exception, err);
303         } catch(const BasePlatformException& err) {
304                 return JSWebAPIErrorFactory::postException(context, exception, err);
305         } catch(const ConversionException& err) {
306                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
307         } catch(const NullPointerException& err) {
308                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
309         }
310
311         EventAddressBookGetPtr dplEvent(new EventAddressBookGet());
312
313         dplEvent->setId(id);
314     dplEvent->setForSynchronousCall();
315
316         Try {
317                 addressBook->get(dplEvent);
318         } Catch(Exception) {
319                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
320                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
321         }
322
323         if (!dplEvent->getResult() || !dplEvent->getContactIsSet())
324         {
325                 std::stringstream oss;
326                 switch (dplEvent->getExceptionCode())
327                 {
328                 case ExceptionCodes::NotFoundException:
329                 case ExceptionCodes::InvalidArgumentException:
330                         LoggerE("Not Found error : " << id);
331                         oss << "No Contact id '" << id << "'";
332                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
333                         break;
334                 case ExceptionCodes::PlatformException:
335                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
336                         break;
337                 default:
338                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
339                         break;
340                 }
341         }
342
343         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
344
345         ContactPtr contact = dplEvent->getContact();
346         JSValueRef result;
347         Try {
348                 result = converter->toJSValueRef(contact);
349         } Catch(Exception) {
350                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
351                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
352         }
353
354         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
355         return result;
356 }
357
358 JSValueRef JSAddressBook::add(JSContextRef context,
359                 JSObjectRef object,
360                 JSObjectRef thisObject,
361                 size_t argumentCount,
362                 const JSValueRef arguments[],
363                 JSValueRef* exception)
364 {
365         LoggerD("entered");
366         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
367         AddressBookPtr addressBook;
368         AddressBookController *controller;
369         JSContextRef gContext;
370
371         Try     {
372                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
373                 if (!controller) {
374                         ThrowMsg(InvalidArgumentException, "No private object.");
375                 }
376                 addressBook = controller->getObject();
377                 gContext = controller->getContext();
378         } Catch(Exception) {
379                 LoggerE("No private object");
380                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
381         }
382
383         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_ADD);
384         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
385
386         try {
387                 ArgumentValidator validator(context, argumentCount, arguments);
388                 validator.toObject(0, false);
389         } catch (const TypeMismatchException& err ) {
390                 return JSWebAPIErrorFactory::postException(context, exception, err);
391         } catch(const BasePlatformException& err) {
392                 return JSWebAPIErrorFactory::postException(context, exception, err);
393         } catch(const ConversionException& err) {
394                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
395         } catch(const NullPointerException& err) {
396                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
397         }
398
399         ContactPtr contact(NULL);
400
401         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
402         Try     {
403                 if (!JSContact::isObjectOfClass(context, arguments[0]))
404                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'Contact object'.");
405                 contact = converter->toContact(arguments[0]);
406         } Catch(Exception) {
407                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
408                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "1st argument must be a 'Contact object'");
409         }
410
411         EventAddressBookAddPtr dplEvent(new EventAddressBookAdd());
412
413         dplEvent->setContact(contact);
414     dplEvent->setForSynchronousCall();
415
416         Try {
417                 addressBook->add(dplEvent);
418         } Catch(Exception) {
419                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
420                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
421         }
422
423         if (!dplEvent->getResult())
424         {
425                 switch (dplEvent->getExceptionCode())
426                 {
427                 case ExceptionCodes::PlatformException:
428                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
429                         break;
430                 case ExceptionCodes::InvalidArgumentException:
431                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "There is Invalid input value");
432                         break;
433                 default:
434                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
435                         break;
436                 }
437         }
438
439         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
440         return JSValueMakeUndefined(context);
441 }
442
443 JSValueRef JSAddressBook::addBatch(JSContextRef context,
444                 JSObjectRef object,
445                 JSObjectRef thisObject,
446                 size_t argumentCount,
447                 const JSValueRef arguments[],
448                 JSValueRef* exception)
449 {
450         LoggerD("entered");
451         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
452         AddressBookPtr addressBook;
453         JSContextRef gContext;
454         AddressBookController *controller;
455
456         bool js2ndParamIsFunction = false;
457         bool js3rdParamIsFunction = false;
458
459         Try     {
460                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
461                 if (!controller) {
462                         ThrowMsg(InvalidArgumentException, "No private object.");
463                 }
464                 addressBook = controller->getObject();
465                 gContext = controller->getContext();
466         } Catch(Exception) {
467                 LoggerE("No private object");
468                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
469         }
470
471         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_ADD_BATCH);
472         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
473
474         try {
475                 ArgumentValidator validator(context, argumentCount, arguments);
476
477                 validator.toObject(0, false);
478                 JSObjectRef successObj = validator.toFunction(1, true);
479                 if(successObj)
480                         js2ndParamIsFunction = true;
481
482                 JSObjectRef errorObj = validator.toFunction(2, true);
483                 if(errorObj)
484                         js3rdParamIsFunction = true;
485
486         } catch (const TypeMismatchException& err ) {
487                 return JSWebAPIErrorFactory::postException(context, exception, err);
488         } catch(const BasePlatformException& err) {
489                 return JSWebAPIErrorFactory::postException(context, exception, err);
490         } catch(const ConversionException& err) {
491                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
492         } catch(const NullPointerException& err) {
493                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
494         }
495
496         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
497
498         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
499
500         if(js2ndParamIsFunction)
501                 callbackManager->setOnSuccess(arguments[1]);
502
503         if(js3rdParamIsFunction)
504                 callbackManager->setOnError(arguments[2]);
505
506         callbackManager->setObject(thisObject);
507
508         EventAddressBookAddBatchPtr dplEvent(new EventAddressBookAddBatch());
509         Try {
510                 dplEvent->setContacts(converter->toContactArray(arguments[0]));
511         } Catch(ConversionException) {
512                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
513                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "1st argument must be an array of 'Contact object'");
514         }
515
516         // set event handler's data
517         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
518         dplEvent->setForAsynchronousCall(controller);
519
520 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
521 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
522
523         Try {
524                 addressBook->addBatch(dplEvent);
525                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
526         } Catch(Exception) {
527                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
528                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
529         }
530
531         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
532 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
533         return JSValueMakeUndefined(context);
534 }
535
536 JSValueRef JSAddressBook::update(JSContextRef context,
537                 JSObjectRef object,
538                 JSObjectRef thisObject,
539                 size_t argumentCount,
540                 const JSValueRef arguments[],
541                 JSValueRef* exception)
542 {
543         LoggerD("entered");
544         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
545         AddressBookPtr addressBook;
546         AddressBookController *controller;
547         JSContextRef gContext;
548
549         Try     {
550                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
551                 if (!controller) {
552                         ThrowMsg(InvalidArgumentException, "No private object.");
553                 }
554                 addressBook = controller->getObject();
555                 gContext = controller->getContext();
556         } Catch(Exception) {
557                 LoggerE("No private object");
558                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
559         }
560
561         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_UPDATE);
562         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
563
564         try {
565                 ArgumentValidator validator(context, argumentCount, arguments);
566                 validator.toObject(0, false);
567
568         } catch (const TypeMismatchException& err ) {
569                 return JSWebAPIErrorFactory::postException(context, exception, err);
570         } catch(const BasePlatformException& err) {
571                 return JSWebAPIErrorFactory::postException(context, exception, err);
572         } catch(const ConversionException& err) {
573                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
574         } catch(const NullPointerException& err) {
575                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
576         }
577
578         ContactPtr contact(NULL);
579
580         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
581         Try     {
582                 if (!JSContact::isObjectOfClass(context, arguments[0]))
583                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'Contact object'.");
584                 contact = converter->toContact(arguments[0]);
585         } Catch(Exception) {
586                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
587                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "1st argument is not a 'Contact object'");
588         }
589
590         EventAddressBookUpdatePtr dplEvent(new EventAddressBookUpdate());
591
592         dplEvent->setContact(contact);
593     dplEvent->setForSynchronousCall();
594
595         Try {
596                 addressBook->update(dplEvent);
597         } Catch(Exception) {
598                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
599                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
600         }
601
602         if (!dplEvent->getResult())
603         {
604                 std::stringstream oss;
605                 switch (dplEvent->getExceptionCode())
606                 {
607                 case ExceptionCodes::NotFoundException:
608                 case ExceptionCodes::InvalidArgumentException:
609                         oss << "No Contact id '" << contact->getId() << "'";
610                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
611                         break;
612                 case ExceptionCodes::PlatformException:
613                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
614                         break;
615                 default:
616                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
617                         break;
618                 }
619         }
620
621         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
622         return JSValueMakeUndefined(context);
623 }
624
625 JSValueRef JSAddressBook::updateBatch(JSContextRef context,
626                 JSObjectRef object,
627                 JSObjectRef thisObject,
628                 size_t argumentCount,
629                 const JSValueRef arguments[],
630                 JSValueRef* exception)
631 {
632         LoggerD("entered");
633         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
634         AddressBookPtr addressBook;
635         JSContextRef gContext;
636         AddressBookController *controller;
637
638         bool js2ndParamIsFunction = false;
639         bool js3rdParamIsFunction = false;
640
641         Try     {
642                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
643                 if (!controller) {
644                         ThrowMsg(InvalidArgumentException, "No private object.");
645                 }
646                 addressBook = controller->getObject();
647                 gContext = controller->getContext();
648         } Catch(Exception) {
649                 LoggerE("No private object");
650                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
651         }
652
653         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_UPDATE_BATCH);
654         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
655
656         try {
657                 ArgumentValidator validator(context, argumentCount, arguments);
658
659                 validator.toObject(0, false);
660
661                 JSObjectRef successObj = validator.toFunction(1, true);
662                 if(successObj)
663                         js2ndParamIsFunction = true;
664
665                 JSObjectRef errorObj = validator.toFunction(2, true);
666                 if(errorObj)
667                         js3rdParamIsFunction = true;
668
669         } catch (const TypeMismatchException& err ) {
670                 return JSWebAPIErrorFactory::postException(context, exception, err);
671         } catch(const BasePlatformException& err) {
672                 return JSWebAPIErrorFactory::postException(context, exception, err);
673         } catch(const ConversionException& err) {
674                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
675         } catch(const NullPointerException& err) {
676                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
677         }
678
679         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
680
681         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
682
683         if(js2ndParamIsFunction)
684                 callbackManager->setOnSuccess(arguments[1]);
685
686         if(js3rdParamIsFunction)
687                 callbackManager->setOnError(arguments[2]);
688
689         callbackManager->setObject(thisObject);
690
691         EventAddressBookUpdateBatchPtr dplEvent(new EventAddressBookUpdateBatch());
692         Try {
693                 dplEvent->setContacts(converter->toContactArray(arguments[0]));
694         } Catch(ConversionException) {
695                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
696                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "3rd argument must be an array of 'Contact object'");
697         }
698
699         // set event handler's data
700         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
701         dplEvent->setForAsynchronousCall(controller);
702
703 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
704 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
705
706         Try {
707                 addressBook->updateBatch(dplEvent);
708                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
709         } Catch(Exception) {
710                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
711                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
712         }
713
714         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
715 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
716         return JSValueMakeUndefined(context);
717 }
718
719 JSValueRef JSAddressBook::remove(JSContextRef context,
720                 JSObjectRef object,
721                 JSObjectRef thisObject,
722                 size_t argumentCount,
723                 const JSValueRef arguments[],
724                 JSValueRef* exception)
725 {
726         LoggerD("entered");
727         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
728         AddressBookPtr addressBook;
729         AddressBookController *controller;
730
731         Try     {
732                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
733                 if (!controller) {
734                         ThrowMsg(InvalidArgumentException, "No private object.");
735                 }
736                 addressBook = controller->getObject();
737         } Catch(Exception) {
738                 LoggerE("No private object");
739                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
740         }
741
742         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_REMOVE);
743         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
744
745         ArgumentValidator validator(context, argumentCount, arguments);
746         string contactId;
747         try     {
748                 contactId = validator.toString(0, false);
749         } catch (const TypeMismatchException& err ) {
750                 return JSWebAPIErrorFactory::postException(context, exception, err);
751         } catch(const BasePlatformException& err) {
752                 return JSWebAPIErrorFactory::postException(context, exception, err);
753         } catch(const ConversionException& err) {
754                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
755         } catch(const NullPointerException& err) {
756                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
757         }
758
759         EventAddressBookRemovePtr dplEvent(new EventAddressBookRemove());
760
761         dplEvent->setContactId(contactId);
762     dplEvent->setForSynchronousCall();
763
764         Try {
765                 addressBook->remove(dplEvent);
766         } Catch(Exception) {
767                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
768                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
769         }
770
771         if (!dplEvent->getResult())
772         {
773                 std::stringstream oss;
774                 switch (dplEvent->getExceptionCode())
775                 {
776                 case ExceptionCodes::NotFoundException:
777                 case ExceptionCodes::InvalidArgumentException:
778                         LoggerE("Not Found error : " << contactId);
779                         oss << "No Contact id '" << contactId << "'";
780                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
781                         break;
782                 case ExceptionCodes::PlatformException:
783                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
784                         break;
785                 default:
786                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
787                         break;
788                 }
789         }
790         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
791         return JSValueMakeUndefined(context);
792 }
793
794 JSValueRef JSAddressBook::removeBatch(JSContextRef context,
795                 JSObjectRef object,
796                 JSObjectRef thisObject,
797                 size_t argumentCount,
798                 const JSValueRef arguments[],
799                 JSValueRef* exception)
800 {
801         LoggerD("entered");
802         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
803         AddressBookPtr addressBook;
804         JSContextRef gContext;
805         AddressBookController *controller;
806
807         bool js2ndParamIsFunction = false;
808         bool js3rdParamIsFunction = false;
809
810         Try     {
811                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
812                 if (!controller) {
813                         ThrowMsg(InvalidArgumentException, "No private object.");
814                 }
815                 addressBook = controller->getObject();
816                 gContext = controller->getContext();
817         } Catch(Exception) {
818                 LoggerE("No private object");
819                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
820         }
821
822         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_REMOVE_BATCH);
823         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
824
825         try {
826                 ArgumentValidator validator(context, argumentCount, arguments);
827
828                 validator.toObject(0, false);
829                 JSObjectRef successObj = validator.toFunction(1, true);
830                 if(successObj)
831                         js2ndParamIsFunction = true;
832
833                 JSObjectRef errorObj = validator.toFunction(2, true);
834                 if(errorObj)
835                         js3rdParamIsFunction = true;
836
837         } catch (const TypeMismatchException& err ) {
838                 return JSWebAPIErrorFactory::postException(context, exception, err);
839         } catch(const BasePlatformException& err) {
840                 return JSWebAPIErrorFactory::postException(context, exception, err);
841         } catch(const ConversionException& err) {
842                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
843         } catch(const NullPointerException& err) {
844                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
845         }
846
847         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
848
849         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
850
851         if(js2ndParamIsFunction)
852                 callbackManager->setOnSuccess(arguments[1]);
853
854         if(js3rdParamIsFunction)
855                 callbackManager->setOnError(arguments[2]);
856
857         callbackManager->setObject(thisObject);
858
859         EventAddressBookRemoveBatchPtr dplEvent(new EventAddressBookRemoveBatch());
860         Try {
861                 dplEvent->setContactIds(converter->toStringArray(arguments[0]));
862         } Catch(ConversionException) {
863                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
864                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "3rd argument must be an array of 'Contact id'");
865         }
866
867         // set event handler's data
868         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
869         dplEvent->setForAsynchronousCall(controller);
870
871 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
872 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
873
874         Try {
875                 addressBook->removeBatch(dplEvent);
876                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
877         } Catch(Exception) {
878                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
879                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
880         }
881
882         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
883 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
884         return JSValueMakeUndefined(context);
885 }
886
887 JSValueRef JSAddressBook::find(JSContextRef context,
888                 JSObjectRef object,
889                 JSObjectRef thisObject,
890                 size_t argumentCount,
891                 const JSValueRef arguments[],
892                 JSValueRef* exception)
893 {
894         LoggerD("entered");
895         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
896         AddressBookPtr addressBook;
897         JSContextRef gContext;
898         AddressBookController *controller;
899
900         bool js2ndParamIsFunction = false;
901         bool js3rdParamIsObject = false;
902         bool js4thParamIsObject = false;
903
904         Try     {
905                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
906                 if (!controller) {
907                         ThrowMsg(InvalidArgumentException, "No private object.");
908                 }
909                 addressBook = controller->getObject();
910                 gContext = controller->getContext();
911         } Catch(Exception) {
912                 LoggerE("No private object");
913                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
914         }
915
916         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_FIND);
917         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
918
919         try {
920                 ArgumentValidator validator(context, argumentCount, arguments);
921
922                 validator.toFunction(0, false);
923                 JSObjectRef errorObj = validator.toFunction(1, true);
924                 if(errorObj)
925                         js2ndParamIsFunction = true;
926
927                 JSObjectRef filterObj = validator.toObject(2, true);
928                 if(filterObj)
929                         js3rdParamIsObject = true;
930
931                 JSObjectRef sortObj = validator.toObject(3, true);
932                 if(sortObj)
933                         js4thParamIsObject = true;
934
935         } catch (const TypeMismatchException& err ) {
936                 return JSWebAPIErrorFactory::postException(context, exception, err);
937         } catch(const BasePlatformException& err) {
938                 return JSWebAPIErrorFactory::postException(context, exception, err);
939         } catch(const ConversionException& err) {
940                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
941         } catch(const NullPointerException& err) {
942                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
943         }
944
945         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
946
947         callbackManager->setOnSuccess(arguments[0]);
948
949         if (js2ndParamIsFunction)
950                 callbackManager->setOnError(arguments[1]);
951
952         callbackManager->setObject(thisObject);
953
954         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
955         ContactFilterConverterFactory::ConverterType filterConverter = ContactFilterConverterFactory::getConverter(context);
956
957         EventAddressBookFindPtr dplEvent(new EventAddressBookFind());
958         Try {
959                 if (js3rdParamIsObject)
960                         dplEvent->setFilter(filterConverter->toFilter(arguments[2]));
961         } Catch(Exception) {
962                 LoggerE("Error on 3rd parameter conversion : " << _rethrown_exception.GetMessage());
963                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "3rd argument must be an 'Filter object' or 'null'");
964         }
965
966         Try {
967                 if (js4thParamIsObject)
968                         dplEvent->setSortMode(filterConverter->toSortMode(arguments[3]));
969         } Catch(Exception) {
970                 LoggerE("Error on 4th parameter conversion : " << _rethrown_exception.GetMessage());
971                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "4th argument must be an 'SortMode object' or 'null'");
972         }
973
974         // set event handler's data
975         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
976         dplEvent->setForAsynchronousCall(controller);
977
978 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
979 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
980
981         Try {
982                 addressBook->find(dplEvent);
983                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
984         } Catch(Exception) {
985                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
986                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
987         }
988
989         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
990 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
991         return JSValueMakeUndefined(context);
992 }
993
994 JSValueRef JSAddressBook::addChangeListener(JSContextRef context,
995                 JSObjectRef object,
996                 JSObjectRef thisObject,
997                 size_t argumentCount,
998                 const JSValueRef arguments[],
999                 JSValueRef* exception)
1000 {
1001         LoggerD("entered");
1002         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1003         AddressBookPtr addressBook;
1004         JSContextRef gContext;
1005         AddressBookController *controller;
1006
1007         bool js2ndParamIsFunction = false;
1008
1009         Try     {
1010                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1011                 if (!controller) {
1012                         ThrowMsg(InvalidArgumentException, "No private object.");
1013                 }
1014                 addressBook = controller->getObject();
1015                 gContext = controller->getContext();
1016         } Catch(Exception) {
1017                 LoggerE("No private object");
1018                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1019         }
1020
1021         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_ADD_CHANGE_LISTENER);
1022         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1023
1024         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
1025         try {
1026                 ArgumentValidator Argvalidator(context, argumentCount, arguments);
1027                 Argvalidator.toObject(0, false);
1028                 JSObjectRef errorObj = Argvalidator.toFunction(1, true);
1029                 if(errorObj)
1030                         js2ndParamIsFunction = true;
1031         } catch (const TypeMismatchException& err ) {
1032                 return JSWebAPIErrorFactory::postException(context, exception, err);
1033         } catch(const BasePlatformException& err) {
1034                 return JSWebAPIErrorFactory::postException(context, exception, err);
1035         } catch(const ConversionException& err) {
1036                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1037         } catch(const NullPointerException& err) {
1038                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1039         }
1040
1041         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1042
1043         JSValueRef oncontactsadded;
1044         JSValueRef oncontactsupdated;
1045         JSValueRef oncontactsdeleted;
1046         Try {
1047                 JSObjectRef callbackObject = converter->toJSObjectRef(arguments[0]);
1048
1049                 oncontactsadded = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "oncontactsadded");
1050                 if (validator->isNullOrUndefined(oncontactsadded))
1051                         oncontactsadded = NULL;
1052                 else if (!validator->isCallback(oncontactsadded)) {
1053                         ThrowMsg(ConversionException, "2nd argument's oncontactsadded attribute is not a 'function'");
1054                 }
1055
1056                 oncontactsupdated = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "oncontactsupdated");
1057                 if (validator->isNullOrUndefined(oncontactsupdated))
1058                         oncontactsupdated = NULL;
1059                 else if (!validator->isCallback(oncontactsupdated)) {
1060                         ThrowMsg(ConversionException, "2nd argument's oncontactsupdated attribute is not a 'function'");
1061                 }
1062
1063                 oncontactsdeleted = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "oncontactsremoved");
1064                 if (validator->isNullOrUndefined(oncontactsdeleted))
1065                         oncontactsdeleted = NULL;
1066                 else if (!validator->isCallback(oncontactsdeleted)) {
1067                         ThrowMsg(ConversionException, "2nd argument's oncontactsremoved attribute is not a 'function'");
1068                 }
1069
1070                 if (oncontactsadded == NULL && oncontactsupdated == NULL && oncontactsdeleted == NULL)
1071                         ThrowMsg(ConversionException, "2nd argument must have at least one function");
1072
1073         } Catch(ConversionException) {
1074                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1075                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
1076         }
1077
1078         JSAddressBookChangeCallbackManagerPtr callbackManager = JSAddressBookChangeCallbackManager::createObject(gContext);
1079
1080         callbackManager->setOnContactsAdded(oncontactsadded);
1081         callbackManager->setOnContactsUpdated(oncontactsupdated);
1082         callbackManager->setOnContactsDeleted(oncontactsdeleted);
1083         if(js2ndParamIsFunction)
1084                 callbackManager->setOnError(arguments[1]);
1085
1086         EventAddressBookChangeListenerEmitterPtr emitter(new EventAddressBookChangeListenerEmitter());
1087
1088         emitter->setEventPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
1089         emitter->setListener(controller);
1090
1091         EventAddressBookAddChangeListenerPtr dplEvent(new EventAddressBookAddChangeListener());
1092
1093         dplEvent->setEmitter(emitter);
1094     dplEvent->setForSynchronousCall();
1095
1096         Try {
1097                 addressBook->addChangeListener(dplEvent);
1098         } Catch(Exception) {
1099                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1100                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1101         }
1102
1103         if (!dplEvent->getResult() || !dplEvent->getIdIsSet())
1104         {
1105                 switch (dplEvent->getExceptionCode())
1106                 {
1107                 case ExceptionCodes::InvalidArgumentException:
1108                 case ExceptionCodes::PlatformException:
1109                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1110                         break;
1111                 default:
1112                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1113                         break;
1114                 }
1115         }
1116
1117         long watchId = dplEvent->getId();
1118
1119         ContactsChangeListenerCancellerPtr canceller = ContactsChangeListenerCancellerPtr(new ContactsChangeListenerCanceller(gContext, thisObject, watchId));
1120         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1121         ContactListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
1122
1123         JSValueRef result;
1124         Try {
1125                 result = JSUtil::toJSValueRef(context, watchId);
1126 //              result = converter->toJSValueRefLong(watchId);
1127         } Catch(Exception) {
1128                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1129                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1130         }
1131         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1132         return result;
1133 }
1134
1135 JSValueRef JSAddressBook::removeChangeListener(JSContextRef context,
1136                 JSObjectRef object,
1137                 JSObjectRef thisObject,
1138                 size_t argumentCount,
1139                 const JSValueRef arguments[],
1140                 JSValueRef* exception)
1141 {
1142         LoggerD("entered");
1143         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1144         AddressBookPtr addressBook;
1145         JSContextRef gContext;
1146         AddressBookController *controller;
1147
1148         Try     {
1149                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1150                 if (!controller) {
1151                         ThrowMsg(InvalidArgumentException, "No private object.");
1152                 }
1153                 addressBook = controller->getObject();
1154                 gContext = controller->getContext();
1155         } Catch(Exception) {
1156                 LoggerE("No private object");
1157                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1158         }
1159
1160         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_REMOVE_CHANGE_LISTENER);
1161         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1162
1163         long watchId = 0;
1164
1165         try {
1166                 ArgumentValidator validator(context, argumentCount, arguments);
1167                 watchId = validator.toLong(0, false);
1168         } catch (const TypeMismatchException& err ) {
1169                 return JSWebAPIErrorFactory::postException(context, exception, err);
1170         } catch(const BasePlatformException& err) {
1171                 return JSWebAPIErrorFactory::postException(context, exception, err);
1172         } catch(const ConversionException& err) {
1173                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1174         } catch(const NullPointerException& err) {
1175                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1176         }
1177
1178         EventAddressBookRemoveChangeListenerPtr dplEvent(new EventAddressBookRemoveChangeListener());
1179
1180         dplEvent->setId(watchId);
1181     dplEvent->setForSynchronousCall();
1182
1183         Try {
1184                 addressBook->removeChangeListener(dplEvent);
1185         } Catch(Exception) {
1186                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1187                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1188         }
1189
1190         ContactsChangeListenerCancellerPtr canceller = ContactsChangeListenerCancellerPtr(new ContactsChangeListenerCanceller(gContext, thisObject, watchId));
1191         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1192         ContactListenerManagerSingleton::Instance().unregisterListener(listenerItem);
1193
1194         if (!dplEvent->getResult())
1195         {
1196                 switch (dplEvent->getExceptionCode())
1197                 {
1198                 case ExceptionCodes::InvalidArgumentException:
1199                 case ExceptionCodes::NotFoundException:
1200                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, "Watch id not found");
1201                         break;
1202                 default:
1203                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1204                         break;
1205                 }
1206         }
1207         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1208         return JSValueMakeUndefined(context);
1209 }
1210
1211 JSValueRef JSAddressBook::getGroup(JSContextRef context,
1212                 JSObjectRef object,
1213                 JSObjectRef thisObject,
1214                 size_t argumentCount,
1215                 const JSValueRef arguments[],
1216                 JSValueRef* exception)
1217 {
1218         LoggerD("entered");
1219         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1220         AddressBookPtr addressBook;
1221         AddressBookController *controller;
1222         JSContextRef gContext;
1223
1224         Try     {
1225                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1226                 if (!controller) {
1227                         ThrowMsg(InvalidArgumentException, "No private object.");
1228                 }
1229                 addressBook = controller->getObject();
1230                 gContext = controller->getContext();
1231         } Catch(Exception) {
1232                 LoggerE("No private object");
1233                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1234         }
1235
1236         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_GET_GROUP);
1237         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1238
1239         string id;
1240
1241         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1242         try     {
1243                 ArgumentValidator validator(context, argumentCount, arguments);
1244                 id = validator.toString(0, false);
1245         } catch (const TypeMismatchException& err ) {
1246                 return JSWebAPIErrorFactory::postException(context, exception, err);
1247         } catch(const BasePlatformException& err) {
1248                 return JSWebAPIErrorFactory::postException(context, exception, err);
1249         } catch(const ConversionException& err) {
1250                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1251         } catch(const NullPointerException& err) {
1252                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1253         }
1254
1255         EventAddressBookGetGroupPtr dplEvent(new EventAddressBookGetGroup());
1256
1257         dplEvent->setId(id);
1258     dplEvent->setForSynchronousCall();
1259
1260         Try {
1261                 addressBook->getGroup(dplEvent);
1262         } Catch(Exception) {
1263                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1264                 return JSWebAPIErrorFactory::postException(context, exception,
1265                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1266         }
1267
1268         if (!dplEvent->getResult() || !dplEvent->getContactGroupIsSet())
1269         {
1270                 std::stringstream oss;
1271                 switch (dplEvent->getExceptionCode())
1272                 {
1273                 case ExceptionCodes::NotFoundException:
1274                 case ExceptionCodes::InvalidArgumentException:
1275                         LoggerE("Not Found error : " << id);
1276                         oss << "No Group id '" << id << "'";
1277                         return JSWebAPIErrorFactory::postException(context, exception,
1278                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1279                         break;
1280                 case ExceptionCodes::PlatformException:
1281                         return JSWebAPIErrorFactory::postException(context, exception,
1282                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1283                         break;
1284                 default:
1285                         return JSWebAPIErrorFactory::postException(context, exception,
1286                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1287                         break;
1288                 }
1289         }
1290
1291         ContactGroupPtr group = dplEvent->getContactGroup();
1292
1293         JSValueRef result;
1294         Try {
1295                 result = converter->toJSValueRef(group);
1296         } Catch(Exception) {
1297                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1298                 return JSWebAPIErrorFactory::postException(context, exception,
1299                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1300         }
1301         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1302         return result;
1303 }
1304
1305 JSValueRef JSAddressBook::addGroup(JSContextRef context,
1306                 JSObjectRef object,
1307                 JSObjectRef thisObject,
1308                 size_t argumentCount,
1309                 const JSValueRef arguments[],
1310                 JSValueRef* exception)
1311 {
1312         LoggerD("entered");
1313         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1314         AddressBookPtr addressBook;
1315         AddressBookController *controller;
1316         JSContextRef gContext;
1317
1318         Try     {
1319                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1320                 if (!controller) {
1321                         ThrowMsg(InvalidArgumentException, "No private object.");
1322                 }
1323                 addressBook = controller->getObject();
1324                 gContext = controller->getContext();
1325         } Catch(Exception) {
1326                 LoggerE("No private object");
1327                 return JSWebAPIErrorFactory::postException(context, exception,
1328                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1329         }
1330
1331         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_ADD_GROUP);
1332         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1333
1334         try {
1335                 ArgumentValidator validator(context, argumentCount, arguments);
1336                 validator.toObject(0, false);
1337
1338         } catch (const TypeMismatchException& err ) {
1339                 return JSWebAPIErrorFactory::postException(context, exception, err);
1340         } catch(const BasePlatformException& err) {
1341                 return JSWebAPIErrorFactory::postException(context, exception, err);
1342         } catch(const ConversionException& err) {
1343                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1344         } catch(const NullPointerException& err) {
1345                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1346         }
1347
1348         ContactGroupPtr group(NULL);
1349
1350         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1351         Try     {
1352                 if (!JSContactGroup::isObjectOfClass(context, arguments[0]))
1353                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'ContactGroup object'.");
1354
1355                 group = converter->toContactGroup(arguments[0]);
1356         } Catch(Exception) {
1357                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1358                 return JSWebAPIErrorFactory::postException(context, exception,
1359                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "1st argument must be a 'ContactGroup object'");
1360         }
1361
1362         EventAddressBookAddGroupPtr dplEvent(new EventAddressBookAddGroup());
1363
1364         dplEvent->setContactGroup(group);
1365     dplEvent->setForSynchronousCall();
1366
1367         Try {
1368                 addressBook->addGroup(dplEvent);
1369         } Catch(Exception) {
1370                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1371                 return JSWebAPIErrorFactory::postException(context, exception,
1372                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1373         }
1374
1375         if (!dplEvent->getResult())
1376         {
1377                 switch (dplEvent->getExceptionCode())
1378                 {
1379                 case ExceptionCodes::PlatformException:
1380                         return JSWebAPIErrorFactory::postException(context, exception,
1381                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1382                         break;
1383                 default:
1384                         return JSWebAPIErrorFactory::postException(context, exception,
1385                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1386                         break;
1387                 }
1388         }
1389         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1390         return JSValueMakeUndefined(context);
1391 }
1392
1393 JSValueRef JSAddressBook::updateGroup(JSContextRef context,
1394                 JSObjectRef object,
1395                 JSObjectRef thisObject,
1396                 size_t argumentCount,
1397                 const JSValueRef arguments[],
1398                 JSValueRef* exception)
1399 {
1400         LoggerD("entered");
1401         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1402         AddressBookPtr addressBook;
1403         AddressBookController *controller;
1404         JSContextRef gContext;
1405
1406         Try     {
1407                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1408                 if (!controller) {
1409                         ThrowMsg(InvalidArgumentException, "No private object.");
1410                 }
1411                 addressBook = controller->getObject();
1412                 gContext = controller->getContext();
1413         } Catch(Exception) {
1414                 LoggerE("No private object");
1415                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1416         }
1417
1418         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_UPDATE_GROUP);
1419         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1420
1421         try {
1422                 ArgumentValidator validator(context, argumentCount, arguments);
1423                 validator.toObject(0, false);
1424
1425         } catch (const TypeMismatchException& err ) {
1426                 return JSWebAPIErrorFactory::postException(context, exception, err);
1427         } catch(const BasePlatformException& err) {
1428                 return JSWebAPIErrorFactory::postException(context, exception, err);
1429         } catch(const ConversionException& err) {
1430                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1431         } catch(const NullPointerException& err) {
1432                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1433         }
1434
1435         ContactGroupPtr contact(NULL);
1436
1437         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1438         Try     {
1439                 if (!JSContactGroup::isObjectOfClass(context, arguments[0]))
1440                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'ContactGroup object'.");
1441                 contact = converter->toContactGroup(arguments[0]);
1442         } Catch(Exception) {
1443                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1444                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "1st argument is not a 'ContactGroup object'");
1445         }
1446
1447         EventAddressBookUpdateGroupPtr dplEvent(new EventAddressBookUpdateGroup());
1448
1449         dplEvent->setContactGroup(contact);
1450     dplEvent->setForSynchronousCall();
1451
1452         Try {
1453                 addressBook->updateGroup(dplEvent);
1454         } Catch(Exception) {
1455                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1456                 return JSWebAPIErrorFactory::postException(context, exception,
1457                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1458         }
1459
1460         if (!dplEvent->getResult())
1461         {
1462                 std::stringstream oss;
1463                 switch (dplEvent->getExceptionCode())
1464                 {
1465                 case ExceptionCodes::NotFoundException:
1466                 case ExceptionCodes::InvalidArgumentException:
1467                         oss << "No Group id '" << contact->getId() << "'";
1468                         return JSWebAPIErrorFactory::postException(context, exception,
1469                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1470                         break;
1471                 case ExceptionCodes::PlatformException:
1472                         return JSWebAPIErrorFactory::postException(context, exception,
1473                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1474                         break;
1475                 default:
1476                         return JSWebAPIErrorFactory::postException(context, exception,
1477                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1478                         break;
1479                 }
1480         }
1481         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1482         return JSValueMakeUndefined(context);
1483 }
1484
1485 JSValueRef JSAddressBook::removeGroup(JSContextRef context,
1486                 JSObjectRef object,
1487                 JSObjectRef thisObject,
1488                 size_t argumentCount,
1489                 const JSValueRef arguments[],
1490                 JSValueRef* exception)
1491 {
1492         LoggerD("entered");
1493         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1494         AddressBookPtr addressBook;
1495         AddressBookController *controller;
1496
1497         Try     {
1498                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1499                 if (!controller) {
1500                         ThrowMsg(InvalidArgumentException, "No private object.");
1501                 }
1502                 addressBook = controller->getObject();
1503         } Catch(Exception) {
1504                 LoggerE("No private object");
1505                 return JSWebAPIErrorFactory::postException(context, exception,
1506                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1507         }
1508
1509         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_REMOVE_GROUP);
1510         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1511
1512         string groupId;
1513
1514         try     {
1515                 ArgumentValidator validator(context, argumentCount, arguments);
1516                 groupId = validator.toString(0, false);
1517         } catch (const TypeMismatchException& err ) {
1518                 return JSWebAPIErrorFactory::postException(context, exception, err);
1519         } catch(const BasePlatformException& err) {
1520                 return JSWebAPIErrorFactory::postException(context, exception, err);
1521         } catch(const ConversionException& err) {
1522                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1523         } catch(const NullPointerException& err) {
1524                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1525         }
1526
1527         EventAddressBookRemoveGroupPtr dplEvent(new EventAddressBookRemoveGroup());
1528
1529         dplEvent->setContactGroupId(groupId);
1530     dplEvent->setForSynchronousCall();
1531
1532         Try {
1533                 addressBook->removeGroup(dplEvent);
1534         } Catch(Exception) {
1535                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1536                 return JSWebAPIErrorFactory::postException(context, exception,
1537                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1538         }
1539
1540         if (!dplEvent->getResult())
1541         {
1542                 std::stringstream oss;
1543                 switch (dplEvent->getExceptionCode())
1544                 {
1545                 case ExceptionCodes::NotFoundException:
1546                 case ExceptionCodes::InvalidArgumentException:
1547                         LoggerE("Not Found error : " << groupId);
1548                         oss << "No Group id '" << groupId << "'";
1549                         return JSWebAPIErrorFactory::postException(context, exception,
1550                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1551                         break;
1552                 case ExceptionCodes::PlatformException:
1553                         return JSWebAPIErrorFactory::postException(context, exception,
1554                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1555                         break;
1556                 default:
1557                         return JSWebAPIErrorFactory::postException(context, exception,
1558                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1559                         break;
1560                 }
1561         }
1562         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1563         return JSValueMakeUndefined(context);
1564 }
1565
1566 JSValueRef JSAddressBook::getGroups(JSContextRef context,
1567                 JSObjectRef object,
1568                 JSObjectRef thisObject,
1569                 size_t argumentCount,
1570                 const JSValueRef arguments[],
1571                 JSValueRef* exception)
1572 {
1573         LoggerD("entered");
1574         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1575         AddressBookPtr addressBook;
1576         AddressBookController *controller;
1577         JSContextRef gContext;
1578
1579         Try     {
1580                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1581                 if (!controller) {
1582                         ThrowMsg(InvalidArgumentException, "No private object.");
1583                 }
1584                 addressBook = controller->getObject();
1585                 gContext = controller->getContext();
1586         } Catch(Exception) {
1587                 LoggerE("No private object");
1588                 return JSWebAPIErrorFactory::postException(context, exception,
1589                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1590         }
1591
1592         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_GET_GROUPS);
1593         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1594
1595         string id;
1596
1597         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1598
1599         EventAddressBookGetGroupsPtr dplEvent(new EventAddressBookGetGroups());
1600
1601     dplEvent->setForSynchronousCall();
1602
1603         Try {
1604                 addressBook->getGroups(dplEvent);
1605         } Catch(Exception) {
1606                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1607                 return JSWebAPIErrorFactory::postException(context, exception,
1608                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1609         }
1610
1611         if (!dplEvent->getResult() || !dplEvent->getContactGroupsIsSet())
1612         {
1613                 std::stringstream oss;
1614                 switch (dplEvent->getExceptionCode())
1615                 {
1616                 case ExceptionCodes::NotFoundException:
1617                 case ExceptionCodes::InvalidArgumentException:
1618                         LoggerE("Not Found error : " << id);
1619                         oss << "No Group id '" << id << "'";
1620                         return JSWebAPIErrorFactory::postException(context, exception,
1621                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1622                         break;
1623                 case ExceptionCodes::PlatformException:
1624                         return JSWebAPIErrorFactory::postException(context, exception,
1625                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1626                         break;
1627                 default:
1628                         return JSWebAPIErrorFactory::postException(context, exception,
1629                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1630                         break;
1631                 }
1632         }
1633
1634         ContactGroupArrayPtr groups = dplEvent->getContactGroups();
1635
1636         JSValueRef result;
1637         Try {
1638                 result = converter->toJSValueRef(groups);
1639         } Catch(Exception) {
1640                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1641                 return JSWebAPIErrorFactory::postException(context, exception,
1642                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1643         }
1644         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1645         return result;
1646 }
1647
1648 } // Contact
1649 } // DeviceAPI