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