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