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