Update change log and spec for wrt-plugins-tizen_0.4.50
[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                         FilterPtr filter = filterConverter->toFilter(arguments[2]);
961                         if(filter)
962                                 dplEvent->setFilter(filter);
963                         else
964                                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "3rd argument must be an Correct 'Filter object' or 'null'");
965                 }
966         } Catch(Exception) {
967                 LoggerE("Error on 3rd parameter conversion : " << _rethrown_exception.GetMessage());
968                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "3rd argument must be an 'Filter object' or 'null'");
969         }
970
971         Try {
972                 if (js4thParamIsObject){
973                         SortModePtr sortMode = filterConverter->toSortMode(arguments[3]);
974                         dplEvent->setSortMode(sortMode);
975                 }
976         } Catch(Exception) {
977                 LoggerE("Error on 4th parameter conversion : " << _rethrown_exception.GetMessage());
978                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "4th argument must be an 'SortMode object' or 'null'");
979         }
980
981         // set event handler's data
982         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
983         dplEvent->setForAsynchronousCall(controller);
984
985 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
986 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
987
988         Try {
989                 addressBook->find(dplEvent);
990                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
991         } Catch(Exception) {
992                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
993                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
994         }
995
996         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
997 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
998         return JSValueMakeUndefined(context);
999 }
1000
1001 JSValueRef JSAddressBook::addChangeListener(JSContextRef context,
1002                 JSObjectRef object,
1003                 JSObjectRef thisObject,
1004                 size_t argumentCount,
1005                 const JSValueRef arguments[],
1006                 JSValueRef* exception)
1007 {
1008         LoggerD("entered");
1009         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1010         AddressBookPtr addressBook;
1011         JSContextRef gContext;
1012         AddressBookController *controller;
1013
1014         bool js2ndParamIsFunction = false;
1015
1016         Try     {
1017                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1018                 if (!controller) {
1019                         ThrowMsg(InvalidArgumentException, "No private object.");
1020                 }
1021                 addressBook = controller->getObject();
1022                 gContext = controller->getContext();
1023         } Catch(Exception) {
1024                 LoggerE("No private object");
1025                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1026         }
1027
1028         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_ADD_CHANGE_LISTENER);
1029         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1030
1031         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
1032         try {
1033                 ArgumentValidator Argvalidator(context, argumentCount, arguments);
1034                 Argvalidator.toObject(0, false);
1035                 JSObjectRef errorObj = Argvalidator.toFunction(1, true);
1036                 if(errorObj)
1037                         js2ndParamIsFunction = true;
1038         } catch (const TypeMismatchException& err ) {
1039                 return JSWebAPIErrorFactory::postException(context, exception, err);
1040         } catch(const BasePlatformException& err) {
1041                 return JSWebAPIErrorFactory::postException(context, exception, err);
1042         } catch(const ConversionException& err) {
1043                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1044         } catch(const NullPointerException& err) {
1045                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1046         }
1047
1048         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1049
1050         JSValueRef oncontactsadded;
1051         JSValueRef oncontactsupdated;
1052         JSValueRef oncontactsdeleted;
1053         Try {
1054                 JSObjectRef callbackObject = converter->toJSObjectRef(arguments[0]);
1055
1056                 oncontactsadded = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "oncontactsadded");
1057                 if (validator->isNullOrUndefined(oncontactsadded))
1058                         oncontactsadded = NULL;
1059                 else if (!validator->isCallback(oncontactsadded)) {
1060                         ThrowMsg(ConversionException, "2nd argument's oncontactsadded attribute is not a 'function'");
1061                 }
1062
1063                 oncontactsupdated = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "oncontactsupdated");
1064                 if (validator->isNullOrUndefined(oncontactsupdated))
1065                         oncontactsupdated = NULL;
1066                 else if (!validator->isCallback(oncontactsupdated)) {
1067                         ThrowMsg(ConversionException, "2nd argument's oncontactsupdated attribute is not a 'function'");
1068                 }
1069
1070                 oncontactsdeleted = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "oncontactsremoved");
1071                 if (validator->isNullOrUndefined(oncontactsdeleted))
1072                         oncontactsdeleted = NULL;
1073                 else if (!validator->isCallback(oncontactsdeleted)) {
1074                         ThrowMsg(ConversionException, "2nd argument's oncontactsremoved attribute is not a 'function'");
1075                 }
1076
1077                 if (oncontactsadded == NULL && oncontactsupdated == NULL && oncontactsdeleted == NULL)
1078                         ThrowMsg(ConversionException, "2nd argument must have at least one function");
1079
1080         } Catch(ConversionException) {
1081                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1082                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
1083         }
1084
1085         JSAddressBookChangeCallbackManagerPtr callbackManager = JSAddressBookChangeCallbackManager::createObject(gContext);
1086
1087         callbackManager->setOnContactsAdded(oncontactsadded);
1088         callbackManager->setOnContactsUpdated(oncontactsupdated);
1089         callbackManager->setOnContactsDeleted(oncontactsdeleted);
1090         if(js2ndParamIsFunction)
1091                 callbackManager->setOnError(arguments[1]);
1092
1093         EventAddressBookChangeListenerEmitterPtr emitter(new EventAddressBookChangeListenerEmitter());
1094
1095         emitter->setEventPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
1096         emitter->setListener(controller);
1097
1098         EventAddressBookAddChangeListenerPtr dplEvent(new EventAddressBookAddChangeListener());
1099
1100         dplEvent->setEmitter(emitter);
1101     dplEvent->setForSynchronousCall();
1102
1103         Try {
1104                 addressBook->addChangeListener(dplEvent);
1105         } Catch(Exception) {
1106                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1107                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1108         }
1109
1110         if (!dplEvent->getResult() || !dplEvent->getIdIsSet())
1111         {
1112                 switch (dplEvent->getExceptionCode())
1113                 {
1114                 case ExceptionCodes::InvalidArgumentException:
1115                 case ExceptionCodes::PlatformException:
1116                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1117                         break;
1118                 default:
1119                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1120                         break;
1121                 }
1122         }
1123
1124         long watchId = dplEvent->getId();
1125
1126         ContactsChangeListenerCancellerPtr canceller = ContactsChangeListenerCancellerPtr(new ContactsChangeListenerCanceller(gContext, thisObject, watchId));
1127         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1128         ContactListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
1129
1130         JSValueRef result;
1131         Try {
1132                 result = JSUtil::toJSValueRef(context, watchId);
1133 //              result = converter->toJSValueRefLong(watchId);
1134         } Catch(Exception) {
1135                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1136                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1137         }
1138         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1139         return result;
1140 }
1141
1142 JSValueRef JSAddressBook::removeChangeListener(JSContextRef context,
1143                 JSObjectRef object,
1144                 JSObjectRef thisObject,
1145                 size_t argumentCount,
1146                 const JSValueRef arguments[],
1147                 JSValueRef* exception)
1148 {
1149         LoggerD("entered");
1150         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1151         AddressBookPtr addressBook;
1152         JSContextRef gContext;
1153         AddressBookController *controller;
1154
1155         Try     {
1156                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1157                 if (!controller) {
1158                         ThrowMsg(InvalidArgumentException, "No private object.");
1159                 }
1160                 addressBook = controller->getObject();
1161                 gContext = controller->getContext();
1162         } Catch(Exception) {
1163                 LoggerE("No private object");
1164                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1165         }
1166
1167         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_REMOVE_CHANGE_LISTENER);
1168         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1169
1170         long watchId = 0;
1171
1172         try {
1173                 ArgumentValidator validator(context, argumentCount, arguments);
1174                 watchId = validator.toLong(0, false);
1175         } catch (const TypeMismatchException& err ) {
1176                 return JSWebAPIErrorFactory::postException(context, exception, err);
1177         } catch(const BasePlatformException& err) {
1178                 return JSWebAPIErrorFactory::postException(context, exception, err);
1179         } catch(const ConversionException& err) {
1180                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1181         } catch(const NullPointerException& err) {
1182                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1183         }
1184
1185         EventAddressBookRemoveChangeListenerPtr dplEvent(new EventAddressBookRemoveChangeListener());
1186
1187         dplEvent->setId(watchId);
1188     dplEvent->setForSynchronousCall();
1189
1190         Try {
1191                 addressBook->removeChangeListener(dplEvent);
1192         } Catch(Exception) {
1193                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1194                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1195         }
1196
1197         ContactsChangeListenerCancellerPtr canceller = ContactsChangeListenerCancellerPtr(new ContactsChangeListenerCanceller(gContext, thisObject, watchId));
1198         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1199         ContactListenerManagerSingleton::Instance().unregisterListener(listenerItem);
1200
1201         if (!dplEvent->getResult())
1202         {
1203                 switch (dplEvent->getExceptionCode())
1204                 {
1205                 case ExceptionCodes::InvalidArgumentException:
1206                 case ExceptionCodes::NotFoundException:
1207                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_FOUND_ERROR, "Watch id not found");
1208                         break;
1209                 default:
1210                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1211                         break;
1212                 }
1213         }
1214         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1215         return JSValueMakeUndefined(context);
1216 }
1217
1218 JSValueRef JSAddressBook::getGroup(JSContextRef context,
1219                 JSObjectRef object,
1220                 JSObjectRef thisObject,
1221                 size_t argumentCount,
1222                 const JSValueRef arguments[],
1223                 JSValueRef* exception)
1224 {
1225         LoggerD("entered");
1226         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1227         AddressBookPtr addressBook;
1228         AddressBookController *controller;
1229         JSContextRef gContext;
1230
1231         Try     {
1232                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1233                 if (!controller) {
1234                         ThrowMsg(InvalidArgumentException, "No private object.");
1235                 }
1236                 addressBook = controller->getObject();
1237                 gContext = controller->getContext();
1238         } Catch(Exception) {
1239                 LoggerE("No private object");
1240                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1241         }
1242
1243         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_GET_GROUP);
1244         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1245
1246         string id;
1247
1248         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1249         try     {
1250                 ArgumentValidator validator(context, argumentCount, arguments);
1251                 id = validator.toString(0, false);
1252         } catch (const TypeMismatchException& err ) {
1253                 return JSWebAPIErrorFactory::postException(context, exception, err);
1254         } catch(const BasePlatformException& err) {
1255                 return JSWebAPIErrorFactory::postException(context, exception, err);
1256         } catch(const ConversionException& err) {
1257                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1258         } catch(const NullPointerException& err) {
1259                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1260         }
1261
1262         EventAddressBookGetGroupPtr dplEvent(new EventAddressBookGetGroup());
1263
1264         dplEvent->setId(id);
1265     dplEvent->setForSynchronousCall();
1266
1267         Try {
1268                 addressBook->getGroup(dplEvent);
1269         } Catch(Exception) {
1270                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1271                 return JSWebAPIErrorFactory::postException(context, exception,
1272                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1273         }
1274
1275         if (!dplEvent->getResult() || !dplEvent->getContactGroupIsSet())
1276         {
1277                 std::stringstream oss;
1278                 switch (dplEvent->getExceptionCode())
1279                 {
1280                 case ExceptionCodes::NotFoundException:
1281                 case ExceptionCodes::InvalidArgumentException:
1282                         LoggerE("Not Found error : " << id);
1283                         oss << "No Group id '" << id << "'";
1284                         return JSWebAPIErrorFactory::postException(context, exception,
1285                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1286                         break;
1287                 case ExceptionCodes::PlatformException:
1288                         return JSWebAPIErrorFactory::postException(context, exception,
1289                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1290                         break;
1291                 default:
1292                         return JSWebAPIErrorFactory::postException(context, exception,
1293                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1294                         break;
1295                 }
1296         }
1297
1298         ContactGroupPtr group = dplEvent->getContactGroup();
1299
1300         JSValueRef result;
1301         Try {
1302                 result = converter->toJSValueRef(group);
1303         } Catch(Exception) {
1304                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1305                 return JSWebAPIErrorFactory::postException(context, exception,
1306                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1307         }
1308         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1309         return result;
1310 }
1311
1312 JSValueRef JSAddressBook::addGroup(JSContextRef context,
1313                 JSObjectRef object,
1314                 JSObjectRef thisObject,
1315                 size_t argumentCount,
1316                 const JSValueRef arguments[],
1317                 JSValueRef* exception)
1318 {
1319         LoggerD("entered");
1320         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1321         AddressBookPtr addressBook;
1322         AddressBookController *controller;
1323         JSContextRef gContext;
1324
1325         Try     {
1326                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1327                 if (!controller) {
1328                         ThrowMsg(InvalidArgumentException, "No private object.");
1329                 }
1330                 addressBook = controller->getObject();
1331                 gContext = controller->getContext();
1332         } Catch(Exception) {
1333                 LoggerE("No private object");
1334                 return JSWebAPIErrorFactory::postException(context, exception,
1335                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1336         }
1337
1338         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_ADD_GROUP);
1339         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1340
1341         try {
1342                 ArgumentValidator validator(context, argumentCount, arguments);
1343                 validator.toObject(0, false);
1344
1345         } catch (const TypeMismatchException& err ) {
1346                 return JSWebAPIErrorFactory::postException(context, exception, err);
1347         } catch(const BasePlatformException& err) {
1348                 return JSWebAPIErrorFactory::postException(context, exception, err);
1349         } catch(const ConversionException& err) {
1350                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1351         } catch(const NullPointerException& err) {
1352                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1353         }
1354
1355         ContactGroupPtr group(NULL);
1356
1357         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1358         Try     {
1359                 if (!JSContactGroup::isObjectOfClass(context, arguments[0]))
1360                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'ContactGroup object'.");
1361
1362                 group = converter->toContactGroup(arguments[0]);
1363         } Catch(Exception) {
1364                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1365                 return JSWebAPIErrorFactory::postException(context, exception,
1366                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "1st argument must be a 'ContactGroup object'");
1367         }
1368
1369         EventAddressBookAddGroupPtr dplEvent(new EventAddressBookAddGroup());
1370
1371         dplEvent->setContactGroup(group);
1372     dplEvent->setForSynchronousCall();
1373
1374         Try {
1375                 addressBook->addGroup(dplEvent);
1376         } Catch(Exception) {
1377                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1378                 return JSWebAPIErrorFactory::postException(context, exception,
1379                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1380         }
1381
1382         if (!dplEvent->getResult())
1383         {
1384                 switch (dplEvent->getExceptionCode())
1385                 {
1386                 case ExceptionCodes::PlatformException:
1387                         return JSWebAPIErrorFactory::postException(context, exception,
1388                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1389                         break;
1390                 default:
1391                         return JSWebAPIErrorFactory::postException(context, exception,
1392                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1393                         break;
1394                 }
1395         }
1396         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1397         return JSValueMakeUndefined(context);
1398 }
1399
1400 JSValueRef JSAddressBook::updateGroup(JSContextRef context,
1401                 JSObjectRef object,
1402                 JSObjectRef thisObject,
1403                 size_t argumentCount,
1404                 const JSValueRef arguments[],
1405                 JSValueRef* exception)
1406 {
1407         LoggerD("entered");
1408         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1409         AddressBookPtr addressBook;
1410         AddressBookController *controller;
1411         JSContextRef gContext;
1412
1413         Try     {
1414                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1415                 if (!controller) {
1416                         ThrowMsg(InvalidArgumentException, "No private object.");
1417                 }
1418                 addressBook = controller->getObject();
1419                 gContext = controller->getContext();
1420         } Catch(Exception) {
1421                 LoggerE("No private object");
1422                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1423         }
1424
1425         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_UPDATE_GROUP);
1426         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1427
1428         try {
1429                 ArgumentValidator validator(context, argumentCount, arguments);
1430                 validator.toObject(0, false);
1431
1432         } catch (const TypeMismatchException& err ) {
1433                 return JSWebAPIErrorFactory::postException(context, exception, err);
1434         } catch(const BasePlatformException& err) {
1435                 return JSWebAPIErrorFactory::postException(context, exception, err);
1436         } catch(const ConversionException& err) {
1437                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1438         } catch(const NullPointerException& err) {
1439                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1440         }
1441
1442         ContactGroupPtr contact(NULL);
1443
1444         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1445         Try     {
1446                 if (!JSContactGroup::isObjectOfClass(context, arguments[0]))
1447                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'ContactGroup object'.");
1448                 contact = converter->toContactGroup(arguments[0]);
1449         } Catch(Exception) {
1450                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1451                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "1st argument is not a 'ContactGroup object'");
1452         }
1453
1454         EventAddressBookUpdateGroupPtr dplEvent(new EventAddressBookUpdateGroup());
1455
1456         dplEvent->setContactGroup(contact);
1457     dplEvent->setForSynchronousCall();
1458
1459         Try {
1460                 addressBook->updateGroup(dplEvent);
1461         } Catch(Exception) {
1462                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1463                 return JSWebAPIErrorFactory::postException(context, exception,
1464                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1465         }
1466
1467         if (!dplEvent->getResult())
1468         {
1469                 std::stringstream oss;
1470                 switch (dplEvent->getExceptionCode())
1471                 {
1472                 case ExceptionCodes::NotFoundException:
1473                 case ExceptionCodes::InvalidArgumentException:
1474                         oss << "No Group id '" << contact->getId() << "'";
1475                         return JSWebAPIErrorFactory::postException(context, exception,
1476                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1477                         break;
1478                 case ExceptionCodes::PlatformException:
1479                         return JSWebAPIErrorFactory::postException(context, exception,
1480                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1481                         break;
1482                 default:
1483                         return JSWebAPIErrorFactory::postException(context, exception,
1484                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1485                         break;
1486                 }
1487         }
1488         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1489         return JSValueMakeUndefined(context);
1490 }
1491
1492 JSValueRef JSAddressBook::removeGroup(JSContextRef context,
1493                 JSObjectRef object,
1494                 JSObjectRef thisObject,
1495                 size_t argumentCount,
1496                 const JSValueRef arguments[],
1497                 JSValueRef* exception)
1498 {
1499         LoggerD("entered");
1500         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1501         AddressBookPtr addressBook;
1502         AddressBookController *controller;
1503
1504         Try     {
1505                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1506                 if (!controller) {
1507                         ThrowMsg(InvalidArgumentException, "No private object.");
1508                 }
1509                 addressBook = controller->getObject();
1510         } Catch(Exception) {
1511                 LoggerE("No private object");
1512                 return JSWebAPIErrorFactory::postException(context, exception,
1513                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1514         }
1515
1516         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_REMOVE_GROUP);
1517         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1518
1519         string groupId;
1520
1521         try     {
1522                 ArgumentValidator validator(context, argumentCount, arguments);
1523                 groupId = validator.toString(0, false);
1524         } catch (const TypeMismatchException& err ) {
1525                 return JSWebAPIErrorFactory::postException(context, exception, err);
1526         } catch(const BasePlatformException& err) {
1527                 return JSWebAPIErrorFactory::postException(context, exception, err);
1528         } catch(const ConversionException& err) {
1529                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1530         } catch(const NullPointerException& err) {
1531                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
1532         }
1533
1534         EventAddressBookRemoveGroupPtr dplEvent(new EventAddressBookRemoveGroup());
1535
1536         dplEvent->setContactGroupId(groupId);
1537     dplEvent->setForSynchronousCall();
1538
1539         Try {
1540                 addressBook->removeGroup(dplEvent);
1541         } Catch(Exception) {
1542                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1543                 return JSWebAPIErrorFactory::postException(context, exception,
1544                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1545         }
1546
1547         if (!dplEvent->getResult())
1548         {
1549                 std::stringstream oss;
1550                 switch (dplEvent->getExceptionCode())
1551                 {
1552                 case ExceptionCodes::NotFoundException:
1553                 case ExceptionCodes::InvalidArgumentException:
1554                         LoggerE("Not Found error : " << groupId);
1555                         oss << "No Group id '" << groupId << "'";
1556                         return JSWebAPIErrorFactory::postException(context, exception,
1557                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1558                         break;
1559                 case ExceptionCodes::PlatformException:
1560                         return JSWebAPIErrorFactory::postException(context, exception,
1561                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1562                         break;
1563                 default:
1564                         return JSWebAPIErrorFactory::postException(context, exception,
1565                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1566                         break;
1567                 }
1568         }
1569         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1570         return JSValueMakeUndefined(context);
1571 }
1572
1573 JSValueRef JSAddressBook::getGroups(JSContextRef context,
1574                 JSObjectRef object,
1575                 JSObjectRef thisObject,
1576                 size_t argumentCount,
1577                 const JSValueRef arguments[],
1578                 JSValueRef* exception)
1579 {
1580         LoggerD("entered");
1581         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1582         AddressBookPtr addressBook;
1583         AddressBookController *controller;
1584         JSContextRef gContext;
1585
1586         Try     {
1587                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1588                 if (!controller) {
1589                         ThrowMsg(InvalidArgumentException, "No private object.");
1590                 }
1591                 addressBook = controller->getObject();
1592                 gContext = controller->getContext();
1593         } Catch(Exception) {
1594                 LoggerE("No private object");
1595                 return JSWebAPIErrorFactory::postException(context, exception,
1596                                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
1597         }
1598
1599         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_ADDRESS_BOOK_GET_GROUPS);
1600         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1601
1602         string id;
1603
1604         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
1605
1606         EventAddressBookGetGroupsPtr dplEvent(new EventAddressBookGetGroups());
1607
1608     dplEvent->setForSynchronousCall();
1609
1610         Try {
1611                 addressBook->getGroups(dplEvent);
1612         } Catch(Exception) {
1613                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1614                 return JSWebAPIErrorFactory::postException(context, exception,
1615                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1616         }
1617
1618         if (!dplEvent->getResult() || !dplEvent->getContactGroupsIsSet())
1619         {
1620                 std::stringstream oss;
1621                 switch (dplEvent->getExceptionCode())
1622                 {
1623                 case ExceptionCodes::NotFoundException:
1624                 case ExceptionCodes::InvalidArgumentException:
1625                         LoggerE("Not Found error : " << id);
1626                         oss << "No Group id '" << id << "'";
1627                         return JSWebAPIErrorFactory::postException(context, exception,
1628                                         JSWebAPIErrorFactory::NOT_FOUND_ERROR, oss.str());
1629                         break;
1630                 case ExceptionCodes::PlatformException:
1631                         return JSWebAPIErrorFactory::postException(context, exception,
1632                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1633                         break;
1634                 default:
1635                         return JSWebAPIErrorFactory::postException(context, exception,
1636                                         JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1637                         break;
1638                 }
1639         }
1640
1641         ContactGroupArrayPtr groups = dplEvent->getContactGroups();
1642
1643         JSValueRef result;
1644         Try {
1645                 result = converter->toJSValueRef(groups);
1646         } Catch(Exception) {
1647                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1648                 return JSWebAPIErrorFactory::postException(context, exception,
1649                                 JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error");
1650         }
1651         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1652         return result;
1653 }
1654
1655 } // Contact
1656 } // DeviceAPI