Update change log and spec for wrt-plugins-tizen_0.4.14
[framework/web/wrt-plugins-tizen.git] / src / Contact / JSContactManager.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        JSContactManager.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.3
22  * @brief
23  */
24
25 #include "JSContactManager.h"
26
27 #include <string>
28 #include <dpl/log/log.h>
29 #include <CommonsJavaScript/JSCallbackManager.h>
30 #include <CommonsJavaScript/Validator.h>
31 #include <CommonsJavaScript/Converter.h>
32 #include <CommonsJavaScript/JSUtils.h>
33 #include <CommonsJavaScript/JSPendingOperation.h>
34 #include <JSTizenExceptionFactory.h>
35 #include <JSTizenException.h>
36 #include <SecurityExceptions.h>
37 #include <FilterConverter.h>
38 #include "ContactFactory.h"
39 #include "ContactTypes.h"
40 #include "plugin_config.h"
41 #include "ContactManagerController.h"
42 #include "ContactAsyncCallbackManager.h"
43 #include "ContactListenerManager.h"
44 #include "ContactConverter.h"
45 #include "JSPerson.h"
46 #include "JSContactManagerChangeCallbackManager.h"
47 #include "ContactFilterConverter.h"
48 #include <ArgumentValidator.h>
49 #include <JSWebAPIError.h>
50
51 namespace DeviceAPI {
52 namespace Contact {
53
54 using namespace DeviceAPI::Common;
55 using namespace DeviceAPI::Tizen;
56 using namespace WrtDeviceApis::Commons;
57 using namespace WrtDeviceApis::CommonsJavaScript;
58
59 JSClassDefinition JSContactManager::m_classInfo = {
60         0,
61         kJSClassAttributeNone,
62         "ContactManager",
63         0,
64         m_property,
65         m_function,
66         Initialize,
67         Finalize,
68         NULL, //HasProperty,
69         NULL, //GetProperty,
70         NULL, //SetProperty,
71         NULL, //DeleteProperty,
72         NULL, //GetPropertyNames,
73         NULL, //CallAsFunction,
74         NULL, //CallAsConstructor,
75         NULL, //HasInstance,
76         NULL, //ConvertToType,
77 };
78
79 const JSClassDefinition* JSContactManager::getClassInfo()
80 {
81         return &m_classInfo;
82 }
83
84 JSStaticValue JSContactManager::m_property[] = {
85         { 0, 0, 0, 0 }
86 };
87
88 JSStaticFunction JSContactManager::m_function[] = {
89         { "getAddressBooks", getAddressBooks, kJSPropertyAttributeNone },
90         { "getDefaultAddressBook", getDefaultAddressBook, kJSPropertyAttributeNone },
91         { "getUnifiedAddressBook", getUnifiedAddressBook, kJSPropertyAttributeNone },
92         { "getAddressBook", getAddressBook, kJSPropertyAttributeNone },
93         { "get", get, kJSPropertyAttributeNone },
94         { "update", update, kJSPropertyAttributeNone },
95         { "updateBatch", updateBatch, kJSPropertyAttributeNone },
96         { "remove", remove, kJSPropertyAttributeNone },
97         { "removeBatch", removeBatch, kJSPropertyAttributeNone },
98         { "find", find, kJSPropertyAttributeNone },
99         { "addChangeListener", addChangeListener, kJSPropertyAttributeNone },
100         { "removeChangeListener", removeChangeListener, kJSPropertyAttributeNone },
101         { 0, 0, 0 }
102 };
103
104 JSClassRef JSContactManager::getClassRef()
105 {
106         if (!m_classRef) {
107                 m_classRef = JSClassCreate(&m_classInfo);
108         }
109         return m_classRef;
110 }
111
112 JSClassRef JSContactManager::m_classRef = JSClassCreate(JSContactManager::getClassInfo());
113
114 void JSContactManager::Initialize(JSContextRef context,
115                 JSObjectRef object)
116 {
117         LogDebug("Entered");
118         ContactManagerPtr contactManager = ContactFactory::getInstance().createContactManager();
119
120         ContactManagerController *priv = new ContactManagerController(context, contactManager);
121
122         JSObjectSetPrivate(object, static_cast<void*>(priv));
123 }
124
125 void JSContactManager::Finalize(JSObjectRef object)
126 {
127         LogDebug("entered");
128         ContactManagerController *priv = static_cast<ContactManagerController*>(JSObjectGetPrivate(object));
129         LogInfo("Delete address book manager");
130         delete priv;
131 }
132
133 JSValueRef JSContactManager::getAddressBooks(JSContextRef context,
134                 JSObjectRef object,
135                 JSObjectRef thisObject,
136                 size_t argumentCount,
137                 const JSValueRef arguments[],
138                 JSValueRef* exception)
139 {
140         LogDebug("Entered");
141         ContactManagerPtr contactManager;
142         JSContextRef gContext;
143         ContactManagerController *controller;
144
145         bool js2ndParamIsFunction = false;
146
147         Try     {
148                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
149                 if (!controller) {
150                         ThrowMsg(InvalidArgumentException, "No private object.");
151                 }
152                 contactManager = controller->getObject();
153                 gContext = controller->getContext();
154         } Catch(Exception) {
155                 LogError("No private object");
156                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
157         }
158
159         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_ADDRESS_BOOKS);
160         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
161
162         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
163         try {
164                 ArgumentValidator validator(context, argumentCount, arguments);
165                 validator.toFunction(0, false);
166                 JSObjectRef errorObj = validator.toFunction(1, true);
167                 if(errorObj)
168                         js2ndParamIsFunction = true;
169         } catch (const TypeMismatchException& err ) {
170                 return JSWebAPIError::throwException(context, exception, err);
171         } catch(const BasePlatformException& err) {
172                 return JSWebAPIError::throwException(context, exception, err);
173         } catch(const ConversionException& err) {
174                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
175         } catch(const NullPointerException& err) {
176                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
177         }
178
179         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
180
181         callbackManager->setOnSuccess(arguments[0]);
182
183         if(js2ndParamIsFunction)
184                 callbackManager->setOnError(arguments[1]);
185
186         callbackManager->setObject(thisObject);
187
188         EventContactManagerGetAddressBooksPtr dplEvent(new EventContactManagerGetAddressBooks());
189
190         // set event handler's data
191         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
192         dplEvent->setForAsynchronousCall(controller);
193
194 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
195 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
196
197         Try {
198                 contactManager->getAddressBooks(dplEvent);
199                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
200         } Catch(Exception) {
201                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
202                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
203         }
204
205 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
206         return JSValueMakeUndefined(context);
207 }
208
209 JSValueRef JSContactManager::getDefaultAddressBook(JSContextRef context,
210                 JSObjectRef object,
211                 JSObjectRef thisObject,
212                 size_t argumentCount,
213                 const JSValueRef arguments[],
214                 JSValueRef* exception)
215 {
216         LogDebug("Entered");
217         ContactManagerController *priv =
218                 static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
219         if (!priv) {
220                 LogError("private object is null");
221                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
222         }
223
224         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_DEFAULT_ADDRESS_BOOK);
225         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
226
227         ContactManagerPtr contactManager;
228         JSContextRef gContext;
229         Try {
230                 contactManager = priv->getObject();
231                 gContext = priv->getContext();
232         } Catch(Exception) {
233                 LogError("contact manager or context is null");
234                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
235         }
236
237         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
238
239         EventContactManagerGetDefaultAddressBookPtr dplEvent(new EventContactManagerGetDefaultAddressBook());
240
241     dplEvent->setForSynchronousCall();
242
243         Try {
244                 contactManager->getDefaultAddressBook(dplEvent);
245         } Catch(Exception) {
246                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
247                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
248         }
249
250         if (!dplEvent->getResult() || !dplEvent->getDefaultAddressBookIsSet())
251         {
252                 std::stringstream oss;
253                 switch (dplEvent->getExceptionCode())
254                 {
255                 case ExceptionCodes::NotFoundException:
256                 case ExceptionCodes::InvalidArgumentException:
257                         LogError("Not Found error");
258                         oss << "No default address book";
259                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
260                         break;
261                 case ExceptionCodes::PlatformException:
262                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
263                         break;
264                 default:
265                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
266                         break;
267                 }
268         }
269
270         AddressBookPtr defaultAddressBook = dplEvent->getDefaultAddressBook();
271
272         JSValueRef resultValue;
273         Try {
274                 resultValue = converter->toJSValueRef(defaultAddressBook);
275         } Catch(Exception){
276                 LogError("Conversion error.");
277                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
278         }
279
280         return resultValue;
281 }
282
283 JSValueRef JSContactManager::getUnifiedAddressBook(JSContextRef context,
284                 JSObjectRef object,
285                 JSObjectRef thisObject,
286                 size_t argumentCount,
287                 const JSValueRef arguments[],
288                 JSValueRef* exception)
289 {
290         LogDebug("Entered");
291         ContactManagerController *priv =
292                 static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
293         if (!priv) {
294                 LogError("private object is null");
295                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
296         }
297
298         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_UNIFIED_ADDRESS_BOOK);
299         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
300
301         ContactManagerPtr contactManager;
302         JSContextRef gContext;
303         Try {
304                 contactManager = priv->getObject();
305                 gContext = priv->getContext();
306         } Catch(Exception) {
307                 LogError("contact manager or context is null");
308                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
309         }
310
311         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
312
313         EventContactManagerGetUnifiedAddressBookPtr dplEvent(new EventContactManagerGetUnifiedAddressBook());
314
315     dplEvent->setForSynchronousCall();
316
317         Try {
318                 contactManager->getUnifiedAddressBook(dplEvent);
319         } Catch(Exception) {
320                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
321                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
322         }
323
324         if (!dplEvent->getResult() || !dplEvent->getUnifiedAddressBookIsSet())
325         {
326                 std::stringstream oss;
327                 switch (dplEvent->getExceptionCode())
328                 {
329                 case ExceptionCodes::NotFoundException:
330                 case ExceptionCodes::InvalidArgumentException:
331                         LogError("Not Found error");
332                         oss << "No default address book";
333                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
334                         break;
335                 case ExceptionCodes::PlatformException:
336                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
337                         break;
338                 default:
339                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
340                         break;
341                 }
342         }
343
344         AddressBookPtr unifiedAddressBook = dplEvent->getUnifiedAddressBook();
345
346         JSValueRef resultValue;
347         Try {
348                 resultValue = converter->toJSValueRef(unifiedAddressBook);
349         } Catch(Exception){
350                 LogError("Conversion error.");
351                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
352         }
353
354         return resultValue;
355 }
356
357 JSValueRef JSContactManager::getAddressBook(JSContextRef context,
358                 JSObjectRef object,
359                 JSObjectRef thisObject,
360                 size_t argumentCount,
361                 const JSValueRef arguments[],
362                 JSValueRef* exception)
363 {
364         LogDebug("Entered");
365         ContactManagerController *priv =
366                 static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
367         if (!priv) {
368                 LogError("private object is null");
369                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
370         }
371
372         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_ADDRESS_BOOK);
373         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
374
375         ContactManagerPtr contactManager;
376         JSContextRef gContext;
377         Try {
378                 contactManager = priv->getObject();
379                 gContext = priv->getContext();
380         } Catch(Exception) {
381                 LogError("contact manager or context is null");
382                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
383         }
384
385         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
386
387         std::string addressBookId;
388         try {
389                 ArgumentValidator validator(context, argumentCount, arguments);
390                 addressBookId = validator.toString(0, false);
391         } catch (const TypeMismatchException& err ) {
392                 return JSWebAPIError::throwException(context, exception, err);
393         } catch(const BasePlatformException& err) {
394                 return JSWebAPIError::throwException(context, exception, err);
395         } catch(const ConversionException& err) {
396                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
397         } catch(const NullPointerException& err) {
398                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
399         }
400
401         EventContactManagerGetAddressBookPtr dplEvent(new EventContactManagerGetAddressBook());
402
403         dplEvent->setAddressBookId(addressBookId);
404     dplEvent->setForSynchronousCall();
405
406         Try {
407                 contactManager->getAddressBook(dplEvent);
408         } Catch(Exception) {
409                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
410                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
411         }
412
413         if (!dplEvent->getResult() || !dplEvent->getAddressBookIsSet())
414         {
415                 std::stringstream oss;
416                 switch (dplEvent->getExceptionCode())
417                 {
418                 case ExceptionCodes::NotFoundException:
419                 case ExceptionCodes::InvalidArgumentException:
420                         LogError("Not Found error : " << addressBookId);
421                         oss << "No Contact id '" << addressBookId << "'";
422                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
423                         break;
424                 case ExceptionCodes::PlatformException:
425                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
426                         break;
427                 default:
428                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
429                         break;
430                 }
431         }
432
433         AddressBookPtr addressBook = dplEvent->getAddressBook();
434
435         JSValueRef resultValue;
436         Try {
437                 resultValue = converter->toJSValueRef(addressBook);
438         } Catch(Exception){
439                 LogError("Conversion error.");
440                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
441         }
442
443         return resultValue;
444 }
445
446 JSValueRef JSContactManager::get(JSContextRef context,
447                 JSObjectRef object,
448                 JSObjectRef thisObject,
449                 size_t argumentCount,
450                 const JSValueRef arguments[],
451                 JSValueRef* exception)
452 {
453         LogDebug("entered");
454         ContactManagerPtr addressBook;
455         ContactManagerController *controller;
456
457         Try     {
458                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
459                 if (!controller) {
460                         ThrowMsg(InvalidArgumentException, "No private object.");
461                 }
462                 addressBook = controller->getObject();
463         } Catch(Exception) {
464                 LogError("No private object");
465                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
466         }
467
468         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET);
469         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
470
471         if (argumentCount < 1) {
472                 /* 1st Argument must be string. */
473                 LogError("1st argument must not be undefined.");
474                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, "No Contact id 'undefined'");
475         }
476
477         std::string id;
478
479         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
480         try     {
481                 ArgumentValidator validator(context, argumentCount, arguments);
482                 id = validator.toString(0, false);
483         } catch (const TypeMismatchException& err ) {
484                 return JSWebAPIError::throwException(context, exception, err);
485         } catch(const BasePlatformException& err) {
486                 return JSWebAPIError::throwException(context, exception, err);
487         } catch(const ConversionException& err) {
488                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
489         } catch(const NullPointerException& err) {
490                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
491         }
492
493         EventContactManagerGetPtr dplEvent(new EventContactManagerGet());
494
495         dplEvent->setId(id);
496     dplEvent->setForSynchronousCall();
497
498         Try {
499                 addressBook->get(dplEvent);
500         } Catch(Exception) {
501                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
502                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
503         }
504
505         if (!dplEvent->getResult() || !dplEvent->getPersonIsSet())
506         {
507                 std::stringstream oss;
508                 switch (dplEvent->getExceptionCode())
509                 {
510                 case ExceptionCodes::NotFoundException:
511                 case ExceptionCodes::InvalidArgumentException:
512                         LogError("Not Found error : " << id);
513                         oss << "No Person id '" << id << "'";
514                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
515                         break;
516                 case ExceptionCodes::PlatformException:
517                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
518                         break;
519                 default:
520                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
521                         break;
522                 }
523         }
524
525         PersonPtr person = dplEvent->getPerson();
526
527         JSValueRef result;
528         Try {
529                 result = converter->toJSValueRef(person);
530         } Catch(Exception) {
531                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
532                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
533         }
534
535         return result;
536 }
537
538 JSValueRef JSContactManager::update(JSContextRef context,
539                 JSObjectRef object,
540                 JSObjectRef thisObject,
541                 size_t argumentCount,
542                 const JSValueRef arguments[],
543                 JSValueRef* exception)
544 {
545         LogDebug("entered");
546         ContactManagerPtr addressBook;
547         ContactManagerController *controller;
548
549         Try     {
550                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
551                 if (!controller) {
552                         ThrowMsg(InvalidArgumentException, "No private object.");
553                 }
554                 addressBook = controller->getObject();
555         } Catch(Exception) {
556                 LogError("No private object");
557                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
558         }
559
560         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_UPDATE);
561         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
562
563         try {
564                 ArgumentValidator validator(context, argumentCount, arguments);
565                 validator.toObject(0, false);
566         } catch (const TypeMismatchException& err ) {
567                 return JSWebAPIError::throwException(context, exception, err);
568         } catch(const BasePlatformException& err) {
569                 return JSWebAPIError::throwException(context, exception, err);
570         } catch(const ConversionException& err) {
571                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
572         } catch(const NullPointerException& err) {
573                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
574         }
575
576         PersonPtr person(NULL);
577
578         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
579         Try     {
580                 if (!JSPerson::isObjectOfClass(context, arguments[0]))
581                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'Contact object'.");
582                 person = converter->toPerson(arguments[0]);
583         } Catch(Exception) {
584                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
585                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "1st argument is not a 'Contact object'");
586         }
587
588         EventContactManagerUpdatePtr dplEvent(new EventContactManagerUpdate());
589
590         dplEvent->setPerson(person);
591     dplEvent->setForSynchronousCall();
592
593         Try {
594                 addressBook->update(dplEvent);
595         } Catch(Exception) {
596                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
597                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
598         }
599
600         if (!dplEvent->getResult())
601         {
602                 std::stringstream oss;
603                 switch (dplEvent->getExceptionCode())
604                 {
605                 case ExceptionCodes::NotFoundException:
606                 case ExceptionCodes::InvalidArgumentException:
607                         oss << "No Contact id '" << person->getId() << "'";
608                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
609                         break;
610                 case ExceptionCodes::PlatformException:
611                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
612                         break;
613                 default:
614                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
615                         break;
616                 }
617         }
618
619         return JSValueMakeUndefined(context);
620 }
621
622 JSValueRef JSContactManager::updateBatch(JSContextRef context,
623                 JSObjectRef object,
624                 JSObjectRef thisObject,
625                 size_t argumentCount,
626                 const JSValueRef arguments[],
627                 JSValueRef* exception)
628 {
629         LogDebug("entered");
630         ContactManagerPtr addressBook;
631         JSContextRef gContext;
632         ContactManagerController *controller;
633
634         bool js2ndParamIsFunction = false;
635         bool js3rdParamIsFunction = false;
636
637         Try     {
638                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
639                 if (!controller) {
640                         ThrowMsg(InvalidArgumentException, "No private object.");
641                 }
642                 addressBook = controller->getObject();
643                 gContext = controller->getContext();
644         } Catch(Exception) {
645                 LogError("No private object");
646                 return JSTizenExceptionFactory::postException(context, exception,
647                                 JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
648         }
649
650         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_UPDATE_BATCH);
651         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
652
653         try {
654                 ArgumentValidator validator(context, argumentCount, arguments);
655
656                 validator.toObject(0, false);
657                 JSObjectRef successObj = validator.toFunction(1, true);
658                 if(successObj)
659                         js2ndParamIsFunction = true;
660
661                 JSObjectRef errorObj = validator.toFunction(2, true);
662                 if(errorObj)
663                         js3rdParamIsFunction = true;
664         } catch (const TypeMismatchException& err ) {
665                 return JSWebAPIError::throwException(context, exception, err);
666         } catch(const BasePlatformException& err) {
667                 return JSWebAPIError::throwException(context, exception, err);
668         } catch(const ConversionException& err) {
669                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
670         } catch(const NullPointerException& err) {
671                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
672         }
673
674         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
675
676         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
677
678         if(js2ndParamIsFunction)
679                 callbackManager->setOnSuccess(arguments[1]);
680
681         if(js3rdParamIsFunction)
682                 callbackManager->setOnError(arguments[2]);
683
684         callbackManager->setObject(thisObject);
685
686         EventContactManagerUpdateBatchPtr dplEvent(new EventContactManagerUpdateBatch());
687         Try {
688                 dplEvent->setPersons(converter->toPersonArray(arguments[0]));
689         } Catch(ConversionException) {
690                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
691                 return JSTizenExceptionFactory::postException(context, exception,
692                                 JSTizenException::TYPE_MISMATCH_ERROR, "3rd argument must be a 'function' or a 'null'");
693         }
694
695         // set event handler's data
696         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
697         dplEvent->setForAsynchronousCall(controller);
698
699 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
700 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
701
702         Try {
703                 addressBook->updateBatch(dplEvent);
704                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
705         } Catch(Exception) {
706                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
707                 return JSTizenExceptionFactory::postException(context, exception,
708                                 JSTizenException::UNKNOWN_ERROR, "Internal error");
709         }
710
711 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
712         return JSValueMakeUndefined(context);
713 }
714
715 JSValueRef JSContactManager::remove(JSContextRef context,
716                 JSObjectRef object,
717                 JSObjectRef thisObject,
718                 size_t argumentCount,
719                 const JSValueRef arguments[],
720                 JSValueRef* exception)
721 {
722         LogDebug("entered");
723         ContactManagerPtr addressBook;
724         ContactManagerController *controller;
725
726         Try     {
727                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
728                 if (!controller) {
729                         ThrowMsg(InvalidArgumentException, "No private object.");
730                 }
731                 addressBook = controller->getObject();
732         } Catch(Exception) {
733                 LogError("No private object");
734                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
735         }
736
737         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_REMOVE);
738         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
739
740         std::string personId;
741
742         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
743         try     {
744                 ArgumentValidator validator(context, argumentCount, arguments);
745                 personId = validator.toString(0, false);
746         } catch (const TypeMismatchException& err ) {
747                 return JSWebAPIError::throwException(context, exception, err);
748         } catch(const BasePlatformException& err) {
749                 return JSWebAPIError::throwException(context, exception, err);
750         } catch(const ConversionException& err) {
751                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
752         } catch(const NullPointerException& err) {
753                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
754         }
755
756         EventContactManagerRemovePtr dplEvent(new EventContactManagerRemove());
757
758         dplEvent->setPersonId(personId);
759     dplEvent->setForSynchronousCall();
760
761         Try {
762                 addressBook->remove(dplEvent);
763         } Catch(Exception) {
764                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
765                 return JSTizenExceptionFactory::postException(context, exception,
766                                 JSTizenException::UNKNOWN_ERROR, "Internal error");
767         }
768
769         if (!dplEvent->getResult())
770         {
771                 std::stringstream oss;
772                 switch (dplEvent->getExceptionCode())
773                 {
774                 case ExceptionCodes::NotFoundException:
775                 case ExceptionCodes::InvalidArgumentException:
776                         LogError("Not Found error : " << personId);
777                         oss << "No Contact id '" << personId << "'";
778                         return JSTizenExceptionFactory::postException(context, exception,
779                                         JSTizenException::NOT_FOUND_ERROR, oss.str());
780                         break;
781                 case ExceptionCodes::PlatformException:
782                         return JSTizenExceptionFactory::postException(context, exception,
783                                         JSTizenException::UNKNOWN_ERROR, "Internal error");
784                         break;
785                 default:
786                         return JSTizenExceptionFactory::postException(context, exception,
787                                         JSTizenException::UNKNOWN_ERROR, "Internal error");
788                         break;
789                 }
790         }
791
792         return JSValueMakeUndefined(context);
793 }
794
795 JSValueRef JSContactManager::removeBatch(JSContextRef context,
796                 JSObjectRef object,
797                 JSObjectRef thisObject,
798                 size_t argumentCount,
799                 const JSValueRef arguments[],
800                 JSValueRef* exception)
801 {
802         LogDebug("entered");
803         ContactManagerPtr addressBook;
804         JSContextRef gContext;
805         ContactManagerController *controller;
806
807         bool js2ndParamIsFunction = false;
808         bool js3rdParamIsFunction = false;
809
810         Try     {
811                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
812                 if (!controller) {
813                         ThrowMsg(InvalidArgumentException, "No private object.");
814                 }
815                 addressBook = controller->getObject();
816                 gContext = controller->getContext();
817         } Catch(Exception) {
818                 LogError("No private object");
819                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
820         }
821
822         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_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         } catch (const TypeMismatchException& err ) {
837                 return JSWebAPIError::throwException(context, exception, err);
838         } catch(const BasePlatformException& err) {
839                 return JSWebAPIError::throwException(context, exception, err);
840         } catch(const ConversionException& err) {
841                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
842         } catch(const NullPointerException& err) {
843                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
844         }
845
846         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
847
848         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
849
850         if(js2ndParamIsFunction)
851                 callbackManager->setOnSuccess(arguments[1]);
852
853         if(js3rdParamIsFunction)
854                 callbackManager->setOnError(arguments[2]);
855
856         callbackManager->setObject(thisObject);
857
858         EventContactManagerRemoveBatchPtr dplEvent(new EventContactManagerRemoveBatch());
859         Try {
860                 dplEvent->setPersonIds(converter->toStringArray(arguments[0]));
861         } Catch(ConversionException) {
862                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
863                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "3rd argument must be an array of 'Contact id'");
864         }
865
866         // set event handler's data
867         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
868         dplEvent->setForAsynchronousCall(controller);
869
870 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
871 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
872
873         Try {
874                 addressBook->removeBatch(dplEvent);
875                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
876         } Catch(Exception) {
877                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
878                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
879         }
880
881 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
882         return JSValueMakeUndefined(context);
883 }
884
885 JSValueRef JSContactManager::find(JSContextRef context,
886                 JSObjectRef object,
887                 JSObjectRef thisObject,
888                 size_t argumentCount,
889                 const JSValueRef arguments[],
890                 JSValueRef* exception)
891 {
892         LogDebug("entered");
893         ContactManagerPtr addressBook;
894         JSContextRef gContext;
895         ContactManagerController *controller;
896
897         bool js2ndParamIsFunction = false;
898         bool js3rdParamIsObject = false;
899         bool js4thParamIsObject = false;
900
901         Try     {
902                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
903                 if (!controller) {
904                         ThrowMsg(InvalidArgumentException, "No private object.");
905                 }
906                 addressBook = controller->getObject();
907                 gContext = controller->getContext();
908         } Catch(Exception) {
909                 LogError("No private object");
910                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
911         }
912
913         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_FIND);
914         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
915
916         try {
917                 ArgumentValidator validator(context, argumentCount, arguments);
918
919                 validator.toFunction(0, false);
920                 JSObjectRef errorObj = validator.toFunction(1, true);
921                 if(errorObj)
922                         js2ndParamIsFunction = true;
923
924                 JSObjectRef filterObj = validator.toObject(2, true);
925                 if(filterObj)
926                         js3rdParamIsObject = true;
927
928                 JSObjectRef sortObj = validator.toObject(3, true);
929                 if(sortObj)
930                         js4thParamIsObject = true;
931
932         } catch (const TypeMismatchException& err ) {
933                 return JSWebAPIError::throwException(context, exception, err);
934         } catch(const BasePlatformException& err) {
935                 return JSWebAPIError::throwException(context, exception, err);
936         } catch(const ConversionException& err) {
937                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
938         } catch(const NullPointerException& err) {
939                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
940         }
941
942         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
943
944         callbackManager->setOnSuccess(arguments[0]);
945
946         if (js2ndParamIsFunction)
947                 callbackManager->setOnError(arguments[1]);
948
949         callbackManager->setObject(thisObject);
950
951         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
952         PersonFilterConverterFactory::ConverterType filterConverter = PersonFilterConverterFactory::getConverter(context);
953
954         EventContactManagerFindPtr dplEvent(new EventContactManagerFind());
955         Try {
956                 if (js3rdParamIsObject)
957                         dplEvent->setFilter(filterConverter->toFilter(arguments[2]));
958         } Catch(Exception) {
959                 LogError("Error on 3rd parameter conversion : " << _rethrown_exception.GetMessage());
960                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "3rd argument must be an 'Filter object' or 'null'");
961         }
962
963         Try {
964                 if (js4thParamIsObject)
965                         dplEvent->setSortMode(filterConverter->toSortMode(arguments[3]));
966         } Catch(Exception) {
967                 LogError("Error on 4th parameter conversion : " << _rethrown_exception.GetMessage());
968                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "4th argument must be an 'SortMode object' or 'null'");
969         }
970
971         // set event handler's data
972         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
973         dplEvent->setForAsynchronousCall(controller);
974
975 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
976 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
977
978         Try {
979                 addressBook->find(dplEvent);
980                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
981         } Catch(Exception) {
982                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
983                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
984         }
985
986 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
987         return JSValueMakeUndefined(context);
988 }
989
990 JSValueRef JSContactManager::addChangeListener(JSContextRef context,
991                 JSObjectRef object,
992                 JSObjectRef thisObject,
993                 size_t argumentCount,
994                 const JSValueRef arguments[],
995                 JSValueRef* exception)
996 {
997         LogDebug("entered");
998         ContactManagerPtr addressBook;
999         JSContextRef gContext;
1000         ContactManagerController *controller;
1001
1002         bool js2ndParamIsFunction = false;
1003
1004         Try     {
1005                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
1006                 if (!controller) {
1007                         ThrowMsg(InvalidArgumentException, "No private object.");
1008                 }
1009                 addressBook = controller->getObject();
1010                 gContext = controller->getContext();
1011         } Catch(Exception) {
1012                 LogError("No private object");
1013                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
1014         }
1015
1016         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_ADD_CHANGE_LISTENER);
1017         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1018
1019         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
1020         try {
1021                 ArgumentValidator Argvalidator(context, argumentCount, arguments);
1022
1023                 Argvalidator.toObject(0, false);
1024                 JSObjectRef errorObj = Argvalidator.toFunction(1, true);
1025                 if(errorObj)
1026                         js2ndParamIsFunction = true;
1027
1028         } catch (const TypeMismatchException& err ) {
1029                 return JSWebAPIError::throwException(context, exception, err);
1030         } catch(const BasePlatformException& err) {
1031                 return JSWebAPIError::throwException(context, exception, err);
1032         } catch(const ConversionException& err) {
1033                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1034         } catch(const NullPointerException& err) {
1035                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1036         }
1037
1038         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1039
1040         JSValueRef onpersonsadded;
1041         JSValueRef onpersonsupdated;
1042         JSValueRef onpersonsdeleted;
1043         Try {
1044                 JSObjectRef callbackObject = converter->toJSObjectRef(arguments[0]);
1045
1046                 onpersonsadded = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onpersonsadded");
1047                 if (validator->isNullOrUndefined(onpersonsadded))
1048                         onpersonsadded = NULL;
1049                 else if (!validator->isCallback(onpersonsadded)) {
1050                         ThrowMsg(ConversionException, "2nd argument's onpersonsadded attribute is not a 'function'");
1051                 }
1052
1053                 onpersonsupdated = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onpersonsupdated");
1054                 if (validator->isNullOrUndefined(onpersonsupdated))
1055                         onpersonsupdated = NULL;
1056                 else if (!validator->isCallback(onpersonsupdated)) {
1057                         ThrowMsg(ConversionException, "2nd argument's onpersonsupdated attribute is not a 'function'");
1058                 }
1059
1060                 onpersonsdeleted = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onpersonsremoved");
1061                 if (validator->isNullOrUndefined(onpersonsdeleted))
1062                         onpersonsdeleted = NULL;
1063                 else if (!validator->isCallback(onpersonsdeleted)) {
1064                         ThrowMsg(ConversionException, "2nd argument's onpersonsremoved attribute is not a 'function'");
1065                 }
1066
1067                 if (onpersonsadded == NULL && onpersonsupdated == NULL && onpersonsdeleted == NULL)
1068                         ThrowMsg(ConversionException, "2nd argument must have at least one function");
1069
1070         } Catch(ConversionException) {
1071                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
1072                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
1073         }
1074
1075         JSContactManagerChangeCallbackManagerPtr callbackManager = JSContactManagerChangeCallbackManager::createObject(gContext);
1076
1077         callbackManager->setOnPersonsAdded(onpersonsadded);
1078         callbackManager->setOnPersonsUpdated(onpersonsupdated);
1079         callbackManager->setOnPersonsDeleted(onpersonsdeleted);
1080         if(js2ndParamIsFunction)
1081                 callbackManager->setOnError(arguments[1]);
1082
1083         EventContactManagerChangeListenerEmitterPtr emitter(new EventContactManagerChangeListenerEmitter());
1084
1085         emitter->setEventPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
1086         emitter->setListener(controller);
1087
1088         EventContactManagerAddChangeListenerPtr dplEvent(new EventContactManagerAddChangeListener());
1089
1090         dplEvent->setEmitter(emitter);
1091     dplEvent->setForSynchronousCall();
1092
1093         Try {
1094                 addressBook->addChangeListener(dplEvent);
1095         } Catch(Exception) {
1096                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
1097                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1098         }
1099
1100         if (!dplEvent->getResult() || !dplEvent->getIdIsSet())
1101         {
1102                 switch (dplEvent->getExceptionCode())
1103                 {
1104                 case ExceptionCodes::InvalidArgumentException:
1105                 case ExceptionCodes::PlatformException:
1106                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1107                         break;
1108                 default:
1109                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1110                         break;
1111                 }
1112         }
1113
1114         long watchId = dplEvent->getId();
1115
1116         PersonsChangeListenerCancellerPtr canceller = PersonsChangeListenerCancellerPtr(new PersonsChangeListenerCanceller(gContext, thisObject, watchId));
1117         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1118         ContactListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
1119
1120         JSValueRef result;
1121         Try {
1122                 result = converter->toJSValueRefLong(watchId);
1123         } Catch(Exception) {
1124                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
1125                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1126         }
1127
1128         return result;
1129 }
1130
1131 JSValueRef JSContactManager::removeChangeListener(JSContextRef context,
1132                 JSObjectRef object,
1133                 JSObjectRef thisObject,
1134                 size_t argumentCount,
1135                 const JSValueRef arguments[],
1136                 JSValueRef* exception)
1137 {
1138         LogDebug("entered");
1139         ContactManagerPtr addressBook;
1140         JSContextRef gContext;
1141         ContactManagerController *controller;
1142
1143         Try     {
1144                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
1145                 if (!controller) {
1146                         ThrowMsg(InvalidArgumentException, "No private object.");
1147                 }
1148                 addressBook = controller->getObject();
1149                 gContext = controller->getContext();
1150         } Catch(Exception) {
1151                 LogError("No private object");
1152                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
1153         }
1154
1155         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_REMOVE_CHANGE_LISTENER);
1156         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1157
1158         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1159
1160         long watchId = 0;
1161         try {
1162                 ArgumentValidator validator(context, argumentCount, arguments);
1163                 watchId = validator.toLong(0, false, 0);
1164         } catch (const TypeMismatchException& err ) {
1165                 return JSWebAPIError::throwException(context, exception, err);
1166         } catch(const BasePlatformException& err) {
1167                 return JSWebAPIError::throwException(context, exception, err);
1168         } catch(const ConversionException& err) {
1169                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1170         } catch(const NullPointerException& err) {
1171                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1172         }
1173
1174         EventContactManagerRemoveChangeListenerPtr dplEvent(new EventContactManagerRemoveChangeListener());
1175
1176         dplEvent->setId(watchId);
1177     dplEvent->setForSynchronousCall();
1178
1179         Try {
1180                 addressBook->removeChangeListener(dplEvent);
1181         } Catch(Exception) {
1182                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
1183                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1184         }
1185
1186         PersonsChangeListenerCancellerPtr canceller = PersonsChangeListenerCancellerPtr(new PersonsChangeListenerCanceller(gContext, thisObject, watchId));
1187         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1188         ContactListenerManagerSingleton::Instance().unregisterListener(listenerItem);
1189
1190         if (!dplEvent->getResult())
1191         {
1192                 switch (dplEvent->getExceptionCode())
1193                 {
1194                 case ExceptionCodes::InvalidArgumentException:
1195                 case ExceptionCodes::NotFoundException:
1196                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, "Watch id not found");
1197                         break;
1198                 default:
1199                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1200                         break;
1201                 }
1202         }
1203
1204         return JSValueMakeUndefined(context);
1205 }
1206
1207 } // Contact
1208 } // DeviceAPI