Beta merge 2
[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 <dpl/assert.h>
26 #include <CommonsJavaScript/Validator.h>
27 #include <CommonsJavaScript/Converter.h>
28 #include <CommonsJavaScript/JSCallbackManager.h>
29 #include <CommonsJavaScript/JSUtils.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 <CommonsJavaScript/JSPendingOperation.h>
38 #include <Tizen/Common/JSTizenExceptionFactory.h>
39 #include <Tizen/Common/JSTizenException.h>
40 #include <Tizen/Common/SecurityExceptions.h>
41 #include <Tizen/Tizen/FilterConverter.h>
42 #include "plugin_config.h"
43 #include "JSAddressBook.h"
44 #include "JSContact.h"
45 #include "ContactConverter.h"
46 #include "AddressBookController.h"
47 #include "JSAddressBookChangeCallbackManager.h"
48
49 using namespace std;
50
51 #define TIZEN_ADDRESS_BOOK_TYPE         "type"
52 #define TIZEN_ADDRESS_BOOK_NAME         "name"
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 using TizenApis::Api::Contact::Contact;
68
69 JSClassRef JSAddressBook::m_jsClassRef = NULL;
70
71 JSClassDefinition JSAddressBook::m_classInfo = {
72         0,
73         kJSClassAttributeNone,
74         TIZEN_ADDRESS_BOOK,
75         0,
76         m_property,
77         m_function,
78         Initialize,
79         Finalize,
80         NULL, //HasProperty,
81         NULL, //GetProperty,
82         NULL, //SetProperty,
83         NULL, //DeleteProperty,
84         NULL, //GetPropertyNames,
85         NULL, //CallAsFunction,
86         NULL, //CallAsConstructor,
87         NULL, //HasInstance,
88         NULL, //ConvertToType,
89 };
90
91 JSStaticValue JSAddressBook::m_property[] = {
92         { TIZEN_ADDRESS_BOOK_TYPE, getProperty, NULL, kJSPropertyAttributeReadOnly },
93         { TIZEN_ADDRESS_BOOK_NAME, getProperty, NULL, kJSPropertyAttributeReadOnly },
94         { 0, 0, 0, 0 }
95 };
96
97 JSStaticFunction JSAddressBook::m_function[] = {
98         { "convertFromString", convertFromString, kJSPropertyAttributeNone },
99         { "convertToString", convertToString, kJSPropertyAttributeNone },
100         { "add", add, kJSPropertyAttributeNone },
101         { "addBatch", addBatch, kJSPropertyAttributeNone },
102         { "update", update, kJSPropertyAttributeNone },
103         { "updateBatch", updateBatch, kJSPropertyAttributeNone },
104         { "remove", remove, kJSPropertyAttributeNone },
105         { "removeBatch", removeBatch, kJSPropertyAttributeNone },
106         { "find", find, kJSPropertyAttributeNone },
107         { "addChangeListener", addChangeListener, kJSPropertyAttributeNone },
108         { "removeChangeListener", removeChangeListener, kJSPropertyAttributeNone },
109         { 0, 0, 0 }
110 };
111
112 const JSClassDefinition* JSAddressBook::getClassInfo()
113 {
114         return &m_classInfo;
115 }
116
117 const JSClassRef JSAddressBook::getClassRef()
118 {
119         LogInfo("entered");
120         if (!m_jsClassRef) {
121                 m_jsClassRef = JSClassCreate(&m_classInfo);
122         }
123         return m_jsClassRef;
124 }
125
126 void JSAddressBook::Initialize(JSContextRef context,
127                 JSObjectRef object)
128 {
129         ////LogDebug("entered");
130         AddressBookController *priv =
131                 static_cast<AddressBookController*>(JSObjectGetPrivate(object));
132         Assert(priv && "Private object not set.");
133 }
134
135 void JSAddressBook::Finalize(JSObjectRef object)
136 {
137         //LogDebug("entered");
138 }
139
140 bool JSAddressBook::isObjectOfClass(JSContextRef context, JSValueRef value)
141 {
142         return JSValueIsObjectOfClass(context, value, getClassRef());
143 }
144
145 IAddressBookPtr JSAddressBook::getAddressBook(JSContextRef context, JSValueRef value)
146 {
147         if (!isObjectOfClass(context, value)) {
148                 Throw(InvalidArgumentException);
149         }
150         JSObjectRef object = JSValueToObject(context, value, NULL);
151         if (!object) {
152                 Throw(InvalidArgumentException);
153         }
154         AddressBookController *priv = static_cast<AddressBookController*>(JSObjectGetPrivate(object));
155         if (!priv) {
156                 Throw(NullPointerException);
157         }
158         return priv->getObject();
159 }
160
161 IAddressBookPtr JSAddressBook::getPrivData(JSObjectRef object)
162 {
163         AddressBookController *priv =
164                 static_cast<AddressBookController*>(JSObjectGetPrivate(object));
165         if (priv) {
166                 return priv->getObject();
167         }
168         Throw(NullPointerException);
169 }
170
171 JSValueRef JSAddressBook::convertFromString(JSContextRef context,
172                 JSObjectRef object,
173                 JSObjectRef thisObject,
174                 size_t argumentCount,
175                 const JSValueRef arguments[],
176                 JSValueRef* exception)
177 {
178         LogDebug("entered");
179         IAddressBookPtr addressBook;
180         JSContextRef gContext;
181         AddressBookController *controller;
182
183         Try     {
184                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
185                 if (!controller) {
186                         ThrowMsg(InvalidArgumentException, "No private object.");
187                 }
188                 addressBook = controller->getObject();
189                 gContext = controller->getContext();
190         } Catch(Exception) {
191                 LogError("No private object");
192                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
193         }
194
195         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_CONVERT_FROM_STRING);
196         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
197
198         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
199         Try {
200                 if (argumentCount != 2)
201                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
202
203                 if (!JSValueIsString(context, arguments[0]))
204                         ThrowMsg(InvalidArgumentException, "1st argument is not string.");
205
206                 if (!JSValueIsString(context, arguments[1]))
207                         ThrowMsg(InvalidArgumentException, "2nd argument is not string.");
208         } Catch(Exception ) {
209                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
210                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
211         }
212
213         string vCardStr;
214         string format;
215
216         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
217         Try
218         {
219                 vCardStr = converter->toString(arguments[0]);
220                 format = converter->toString(arguments[1]);
221         }
222         Catch(Exception) {
223                 LogError("Error on conversion " << _rethrown_exception.GetMessage());
224                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
225         }
226
227         ContactPropertiesPtr contactProperties;
228         Try {
229                 contactProperties = addressBook->convertFromString(vCardStr, format);
230         } Catch(UnsupportedException) {
231                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
232                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, "Unsupported format");
233         } Catch(Exception) {
234                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
235                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
236         }
237
238         JSValueRef result;
239         Try {
240                 result = converter->toJSValueRef(contactProperties);
241         } Catch(Exception) {
242                 LogError("Error on conversion");
243                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
244         }
245
246         return result;
247 }
248
249 JSValueRef JSAddressBook::convertToString(JSContextRef context,
250                 JSObjectRef object,
251                 JSObjectRef thisObject,
252                 size_t argumentCount,
253                 const JSValueRef arguments[],
254                 JSValueRef* exception)
255 {
256         LogDebug("entered");
257         IAddressBookPtr addressBook;
258         JSContextRef gContext;
259         AddressBookController *controller;
260
261         Try     {
262                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
263                 if (!controller) {
264                         ThrowMsg(InvalidArgumentException, "No private object.");
265                 }
266                 addressBook = controller->getObject();
267                 gContext = controller->getContext();
268         } Catch(Exception) {
269                 LogError("No private object");
270                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
271         }
272
273         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_CONVERT_TO_STRING);
274         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
275
276         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
277         Try {
278                 if (argumentCount != 2)
279                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
280
281                 if (!JSContact::isObjectOfClass(context, arguments[0]))
282                         ThrowMsg(InvalidArgumentException, "1st argument is not contact object.");
283
284                 if (!JSValueIsString(context, arguments[1]))
285                         ThrowMsg(InvalidArgumentException, "2nd argument is not string.");
286         } Catch(Exception ) {
287                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
288                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
289         }
290
291         ContactPtr contact;
292         string format;
293
294         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
295         Try     {
296                 contact = converter->toContact(arguments[0]);
297                 format = converter->toString(arguments[1]);
298         } Catch(Exception) {
299                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
300                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
301         }
302
303         string vCard;
304         Try {
305                 vCard = addressBook->convertToString(contact, format);
306         } Catch(UnsupportedException) {
307                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
308                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, "Unsupported format");
309         } Catch(Exception) {
310                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
311                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
312         }
313
314         JSValueRef result;
315         Try {
316                 result = converter->toJSValueRef(vCard);
317         } Catch(Exception) {
318                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
319                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
320         }
321
322         return result;
323 }
324
325 JSValueRef JSAddressBook::add(JSContextRef context,
326                 JSObjectRef object,
327                 JSObjectRef thisObject,
328                 size_t argumentCount,
329                 const JSValueRef arguments[],
330                 JSValueRef* exception)
331 {
332         LogDebug("entered");
333         IAddressBookPtr addressBook;
334         JSContextRef gContext;
335         AddressBookController *controller;
336
337         Try     {
338                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
339                 if (!controller) {
340                         ThrowMsg(InvalidArgumentException, "No private object.");
341                 }
342                 addressBook = controller->getObject();
343                 gContext = controller->getContext();
344         } Catch(Exception) {
345                 LogError("No private object");
346                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
347         }
348
349         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_ADD);
350         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
351
352         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
353         Try {
354                 if (argumentCount != 1)
355                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
356
357                 if (!JSValueIsObject(context, arguments[0]))
358                         ThrowMsg(InvalidArgumentException, "1st argument is not object.");
359
360         } Catch(Exception ) {
361                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
362                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
363         }
364
365         ContactPropertiesPtr contactProperties;
366
367         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
368         Try     {
369                 contactProperties = converter->toContactProperties(arguments[0]);
370         } Catch(Exception) {
371                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
372                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
373         }
374
375         ContactPtr contact(NULL);
376         Try {
377                 contact = addressBook->add(contactProperties);
378         } Catch(Exception) {
379                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
380                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
381         }
382
383         JSValueRef result;
384         Try {
385                 result = converter->toJSValueRef(contact);
386         } Catch(Exception) {
387                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
388                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
389         }
390
391         return result;
392 }
393
394 JSValueRef JSAddressBook::addBatch(JSContextRef context,
395                 JSObjectRef object,
396                 JSObjectRef thisObject,
397                 size_t argumentCount,
398                 const JSValueRef arguments[],
399                 JSValueRef* exception)
400 {
401         LogDebug("entered");
402         IAddressBookPtr addressBook;
403         JSContextRef gContext;
404         AddressBookController *controller;
405
406         Try     {
407                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
408                 if (!controller) {
409                         ThrowMsg(InvalidArgumentException, "No private object.");
410                 }
411                 addressBook = controller->getObject();
412                 gContext = controller->getContext();
413         } Catch(Exception) {
414                 LogError("No private object");
415                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
416         }
417
418         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_ADD_BATCH);
419         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
420
421         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
422         Try {
423                 if (argumentCount < 1 || argumentCount > 3)
424                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
425
426                 if (!JSIsArrayValue(context, arguments[0]))
427                         ThrowMsg(InvalidArgumentException, "1st argument is not array.");
428
429                 if (argumentCount >= 2)
430                 {
431                         if (!validator->isCallback(arguments[1]))
432                                 ThrowMsg(InvalidArgumentException, "2nd argument is not function.");
433                 }
434
435                 if (argumentCount >= 3)
436                 {
437                         if (!validator->isCallback(arguments[2]))
438                                 ThrowMsg(InvalidArgumentException, "3rd argument is not function.");
439                 }
440
441         } Catch(Exception ) {
442                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
443                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
444         }
445
446         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
447
448         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
449
450         if(argumentCount >= 2)
451                 callbackManager->setOnSuccess(arguments[1]);
452
453         if(argumentCount >= 3)
454                 callbackManager->setOnError(arguments[2]);
455
456         EventAddressBookAddBatchPtr dplEvent(new EventAddressBookAddBatch());
457         Try {
458                 dplEvent->setContactProperties(converter->toContactPropertiesArray(arguments[0]));
459         } Catch(ConversionException) {
460                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
461                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
462         }
463
464         // set event handler's data
465         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
466         dplEvent->setForAsynchronousCall(controller);
467
468         //DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
469         //AddressBookAddBatchPendingOperation *gcPendingOperation = new AddressBookAddBatchPendingOperation(eventContr);
470
471         Try {
472                 addressBook->addBatch(dplEvent);
473         } Catch(Exception) {
474                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
475                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
476         }
477
478         //return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
479         return JSValueMakeUndefined(context);
480 }
481
482 JSValueRef JSAddressBook::update(JSContextRef context,
483                 JSObjectRef object,
484                 JSObjectRef thisObject,
485                 size_t argumentCount,
486                 const JSValueRef arguments[],
487                 JSValueRef* exception)
488 {
489         LogDebug("entered");
490         IAddressBookPtr addressBook;
491         JSContextRef gContext;
492         AddressBookController *controller;
493
494         Try     {
495                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
496                 if (!controller) {
497                         ThrowMsg(InvalidArgumentException, "No private object.");
498                 }
499                 addressBook = controller->getObject();
500                 gContext = controller->getContext();
501         } Catch(Exception) {
502                 LogError("No private object");
503                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
504         }
505
506         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_UPDATE);
507         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
508
509         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
510         Try {
511                 if (argumentCount != 1)
512                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
513
514                 if (!JSContact::isObjectOfClass(context, arguments[0]))
515                         ThrowMsg(InvalidArgumentException, "1st argument is wrong object.");
516         } Catch(Exception ) {
517                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
518                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
519         }
520
521         ContactPtr contact;
522
523         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
524         Try     {
525                 contact = converter->toContact(arguments[0]);
526         } Catch(Exception) {
527                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
528                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
529         }
530
531         Try {
532                 addressBook->update(contact);
533         } Catch(Exception) {
534                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
535                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
536         }
537
538         JSValueRef result = JSValueMakeUndefined(context);
539
540         return result;
541 }
542
543 JSValueRef JSAddressBook::updateBatch(JSContextRef context,
544                 JSObjectRef object,
545                 JSObjectRef thisObject,
546                 size_t argumentCount,
547                 const JSValueRef arguments[],
548                 JSValueRef* exception)
549 {
550         LogDebug("entered");
551         IAddressBookPtr addressBook;
552         JSContextRef gContext;
553         AddressBookController *controller;
554
555         Try     {
556                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
557                 if (!controller) {
558                         ThrowMsg(InvalidArgumentException, "No private object.");
559                 }
560                 addressBook = controller->getObject();
561                 gContext = controller->getContext();
562         } Catch(Exception) {
563                 LogError("No private object");
564                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
565         }
566
567         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_UPDATE_BATCH);
568         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
569
570         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
571         Try {
572                 if (argumentCount < 1 || argumentCount > 3)
573                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
574
575                 if (!JSIsArrayValue(context, arguments[0]))
576                         ThrowMsg(InvalidArgumentException, "1st argument is not array.");
577
578                 if (argumentCount >= 2)
579                 {
580                         if (!validator->isCallback(arguments[1]))
581                                 ThrowMsg(InvalidArgumentException, "2nd argument is not function.");
582                 }
583
584                 if (argumentCount >= 3)
585                 {
586                         if (!validator->isCallback(arguments[2]))
587                                 ThrowMsg(InvalidArgumentException, "3rd argument is not function.");
588                 }
589         } Catch(Exception ) {
590                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
591                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
592         }
593
594         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
595
596         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
597
598         if(argumentCount >= 2)
599                 callbackManager->setOnSuccess(arguments[1]);
600
601         if(argumentCount >= 3)
602                 callbackManager->setOnError(arguments[2]);
603
604         EventAddressBookUpdateBatchPtr dplEvent(new EventAddressBookUpdateBatch());
605         Try {
606                 dplEvent->setContacts(converter->toContactArray(arguments[0]));
607         } Catch(ConversionException) {
608                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
609                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
610         }
611
612         // set event handler's data
613         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
614         dplEvent->setForAsynchronousCall(controller);
615
616         //DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
617         //AddressBookUpdateBatchPendingOperation *gcPendingOperation = new AddressBookUpdateBatchPendingOperation(eventContr);
618
619         Try {
620                 addressBook->updateBatch(dplEvent);
621         } Catch(Exception) {
622                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
623                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
624         }
625
626         //return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
627         return JSValueMakeUndefined(context);
628 }
629
630 JSValueRef JSAddressBook::remove(JSContextRef context,
631                 JSObjectRef object,
632                 JSObjectRef thisObject,
633                 size_t argumentCount,
634                 const JSValueRef arguments[],
635                 JSValueRef* exception)
636 {
637         LogDebug("entered");
638         IAddressBookPtr addressBook;
639         JSContextRef gContext;
640         AddressBookController *controller;
641
642         Try     {
643                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
644                 if (!controller) {
645                         ThrowMsg(InvalidArgumentException, "No private object.");
646                 }
647                 addressBook = controller->getObject();
648                 gContext = controller->getContext();
649         } Catch(Exception) {
650                 LogError("No private object");
651                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
652         }
653
654         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_REMOVE);
655         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
656
657         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
658         Try {
659                 if (argumentCount != 1)
660                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
661
662                 if (!JSValueIsString(context, arguments[0]))
663                         ThrowMsg(InvalidArgumentException, "1st argument is wrong object.");
664         } Catch(Exception ) {
665                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
666                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
667         }
668
669         string contactId;
670
671         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
672         Try     {
673                 contactId = converter->toString(arguments[0]);
674         } Catch(Exception) {
675                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
676                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
677         }
678
679         Try {
680                 addressBook->remove(contactId);
681         } Catch(NotFoundException) {
682                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
683                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, "Contact id not found");
684         } Catch(Exception) {
685                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
686                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
687         }
688
689         JSValueRef result = JSValueMakeUndefined(context);
690
691         return result;
692 }
693
694 JSValueRef JSAddressBook::removeBatch(JSContextRef context,
695                 JSObjectRef object,
696                 JSObjectRef thisObject,
697                 size_t argumentCount,
698                 const JSValueRef arguments[],
699                 JSValueRef* exception)
700 {
701         LogDebug("entered");
702         IAddressBookPtr 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(controller->getContext(), CONTACT_FUNCTION_API_REMOVE_BATCH);
719         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
720
721         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
722         Try {
723                 if (argumentCount < 1 || argumentCount > 3)
724                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
725
726                 if (!JSIsArrayValue(context, arguments[0]))
727                         ThrowMsg(InvalidArgumentException, "1st argument is not array.");
728
729                 if (argumentCount >= 2)
730                 {
731                         if (!validator->isCallback(arguments[1]))
732                                 ThrowMsg(InvalidArgumentException, "2nd argument is not function.");
733                 }
734
735                 if (argumentCount >= 3)
736                 {
737                         if (!validator->isCallback(arguments[2]))
738                                 ThrowMsg(InvalidArgumentException, "3rd argument is not function.");
739                 }
740         } Catch(Exception ) {
741                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
742                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
743         }
744
745         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
746
747         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
748
749         if(argumentCount >= 2)
750                 callbackManager->setOnSuccess(arguments[1]);
751
752         if(argumentCount >= 3)
753                 callbackManager->setOnError(arguments[2]);
754
755         EventAddressBookRemoveBatchPtr dplEvent(new EventAddressBookRemoveBatch());
756         Try {
757                 dplEvent->setContactIds(converter->toStringArray(arguments[0]));
758         } Catch(ConversionException) {
759                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
760                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
761         }
762
763         // set event handler's data
764         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
765         dplEvent->setForAsynchronousCall(controller);
766
767         //DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
768         //AddressBookRemoveBatchPendingOperation *gcPendingOperation = new AddressBookRemoveBatchPendingOperation(eventContr);
769
770         Try {
771                 addressBook->removeBatch(dplEvent);
772         } Catch(Exception) {
773                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
774                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
775         }
776
777         //return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
778         return JSValueMakeUndefined(context);
779 }
780
781 JSValueRef JSAddressBook::find(JSContextRef context,
782                 JSObjectRef object,
783                 JSObjectRef thisObject,
784                 size_t argumentCount,
785                 const JSValueRef arguments[],
786                 JSValueRef* exception)
787 {
788         LogDebug("entered");
789         IAddressBookPtr addressBook;
790         JSContextRef gContext;
791         AddressBookController *controller;
792
793         Try     {
794                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
795                 if (!controller) {
796                         ThrowMsg(InvalidArgumentException, "No private object.");
797                 }
798                 addressBook = controller->getObject();
799                 gContext = controller->getContext();
800         } Catch(Exception) {
801                 LogError("No private object");
802                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
803         }
804
805         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_FIND);
806         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
807
808         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
809         Try {
810                 if (argumentCount < 1 || argumentCount > 4)
811                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
812
813                 if (!validator->isCallback(arguments[0]))
814                         ThrowMsg(InvalidArgumentException, "1st argument is not function.");
815
816                 if (argumentCount >= 2)
817                 {
818                         if (!validator->isCallback(arguments[1]))
819                                 ThrowMsg(InvalidArgumentException, "2nd argument is not function.");
820                 }
821
822                 if (argumentCount >= 3)
823                 {
824                         if (!JSValueIsObject(context, arguments[2]) && !JSValueIsNull(context, arguments[2]))
825                                 ThrowMsg(InvalidArgumentException, "3rd argument is not object nor null.");
826                 }
827
828                 if (argumentCount >= 4)
829                 {
830                         if (!JSValueIsObject(context, arguments[3]) && !JSValueIsNull(context, arguments[3]))
831                                 ThrowMsg(InvalidArgumentException, "4th argument is not object nor null.");
832                 }
833         } Catch(Exception ) {
834                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
835                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
836         }
837
838         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
839
840         callbackManager->setOnSuccess(arguments[0]);
841         if (argumentCount >= 2)
842                 callbackManager->setOnError(arguments[1]);
843
844         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
845         FilterConverterFactory::ConverterType filterConverter = FilterConverterFactory::getConverter(context);
846
847         EventAddressBookFindPtr dplEvent(new EventAddressBookFind());
848         Try {
849                 if (argumentCount >= 3 && !JSValueIsNull(context, arguments[2]))
850                         dplEvent->setFilter(filterConverter->toFilter(arguments[2]));
851
852                 if (argumentCount >= 4 && !JSValueIsNull(context, arguments[3]))
853                         dplEvent->setSortModes(filterConverter->toSortModeArray(arguments[3]));
854         } Catch(Exception) {
855                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
856                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
857         }
858
859         // set event handler's data
860         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
861         dplEvent->setForAsynchronousCall(controller);
862
863         //DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
864         //AddressBookFindPendingOperation *gcPendingOperation = new AddressBookFindPendingOperation(eventContr);
865
866         Try {
867                 addressBook->find(dplEvent);
868         } Catch(Exception) {
869                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
870                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
871         }
872
873         //return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
874         return JSValueMakeUndefined(context);
875 }
876
877 JSValueRef JSAddressBook::addChangeListener(JSContextRef context,
878                 JSObjectRef object,
879                 JSObjectRef thisObject,
880                 size_t argumentCount,
881                 const JSValueRef arguments[],
882                 JSValueRef* exception)
883 {
884         LogDebug("entered");
885         IAddressBookPtr addressBook;
886         JSContextRef gContext;
887         AddressBookController *controller;
888
889         Try     {
890                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
891                 if (!controller) {
892                         ThrowMsg(InvalidArgumentException, "No private object.");
893                 }
894                 addressBook = controller->getObject();
895                 gContext = controller->getContext();
896         } Catch(Exception) {
897                 LogError("No private object");
898                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Wrong object");
899         }
900
901         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_ADD_CHANGE_LISTENER);
902         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
903
904         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
905         Try {
906                 if (argumentCount < 1 || argumentCount > 2)
907                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
908
909                 if (!JSValueIsObject(context, arguments[0]))
910                         ThrowMsg(InvalidArgumentException, "1st argument is not object.");
911
912                 if (argumentCount >= 2)
913                 {
914                         if (!validator->isCallback(arguments[1]))
915                                 ThrowMsg(InvalidArgumentException, "2nd argument is not function.");
916                 }
917         } Catch(Exception ) {
918                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
919                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
920         }
921
922         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
923
924         JSValueRef oncontactsadded;
925         JSValueRef oncontactsupdated;
926         JSValueRef oncontactsdeleted;
927         JSValueRef onaddressbookreset;
928         Try {
929                 JSObjectRef callbackObject = converter->toJSObjectRef(arguments[0]);
930
931                 oncontactsadded = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onContactsAdded");
932                 if (validator->isNullOrUndefined(oncontactsadded))
933                         oncontactsadded = NULL;
934                 else if (!validator->isCallback(oncontactsadded)) {
935                         ThrowMsg(ConversionException, "Not a valid callback (onContactsAdded)");
936                 }
937
938                 oncontactsupdated = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onContactsUpdated");
939                 if (validator->isNullOrUndefined(oncontactsupdated))
940                         oncontactsupdated = NULL;
941                 else if (!validator->isCallback(oncontactsupdated)) {
942                         ThrowMsg(ConversionException, "Not a valid callback (onContactsUpdated)");
943                 }
944
945                 oncontactsdeleted = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onContactsRemoved");
946                 if (validator->isNullOrUndefined(oncontactsdeleted))
947                         oncontactsdeleted = NULL;
948                 else if (!validator->isCallback(oncontactsdeleted)) {
949                         ThrowMsg(ConversionException, "Not a valid callback (onContactsRemoved)");
950                 }
951
952                 onaddressbookreset = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onAddressBookReset");
953                 if (validator->isNullOrUndefined(onaddressbookreset))
954                         onaddressbookreset = NULL;
955                 else if (!validator->isCallback(onaddressbookreset)) {
956                         ThrowMsg(ConversionException, "Not a valid callback (onAddressBookReset)");
957                 }
958         } Catch(ConversionException) {
959                 LogError("Error on conversion : " << _rethrown_exception.GetMessage());
960                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
961         }
962
963         JSAddressBookChangeCallbackManagerPtr callbackManager = JSAddressBookChangeCallbackManager::createObject(gContext);
964
965         callbackManager->setOnContactsAdded(oncontactsadded);
966         callbackManager->setOnContactsUpdated(oncontactsupdated);
967         callbackManager->setOnContactsDeleted(oncontactsdeleted);
968         callbackManager->setOnAddressBookReset(onaddressbookreset);
969         if(argumentCount >= 2)
970                 callbackManager->setOnError(arguments[1]);
971
972         EventAddressBookChangeListenerEmitterPtr emitter(new EventAddressBookChangeListenerEmitter());
973
974         emitter->setEventPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
975         emitter->setListener(controller);
976
977         long watchId;
978         Try {
979                 watchId = addressBook->addChangeListener(emitter);
980         } Catch(Exception) {
981                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
982                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
983         }
984
985         return converter->toJSValueRefLong(watchId);
986 }
987
988 JSValueRef JSAddressBook::removeChangeListener(JSContextRef context,
989                 JSObjectRef object,
990                 JSObjectRef thisObject,
991                 size_t argumentCount,
992                 const JSValueRef arguments[],
993                 JSValueRef* exception)
994 {
995         LogDebug("entered");
996         IAddressBookPtr addressBook;
997         JSContextRef gContext;
998         AddressBookController *controller;
999
1000         Try     {
1001                 controller = static_cast<AddressBookController*>(JSObjectGetPrivate(thisObject));
1002                 if (!controller) {
1003                         ThrowMsg(InvalidArgumentException, "No private object.");
1004                 }
1005                 addressBook = controller->getObject();
1006                 gContext = controller->getContext();
1007         } Catch(Exception) {
1008                 LogError("No private object");
1009                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Wrong object");
1010         }
1011
1012         AceSecurityStatus status = CONTACT_CHECK_ACCESS(controller->getContext(), CONTACT_FUNCTION_API_REMOVE_CHANGE_LISTENER);
1013         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1014
1015         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
1016         Try {
1017                 if (argumentCount != 1)
1018                         ThrowMsg(InvalidArgumentException, "Wrong arguments count.");
1019
1020                 if (!JSValueIsNumber(context, arguments[0]))
1021                         ThrowMsg(InvalidArgumentException, "1st argument is not object.");
1022         } Catch(Exception ) {
1023                 LogError("Argument type mismatch : " << _rethrown_exception.GetMessage());
1024                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong arguments");
1025         }
1026
1027         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1028
1029         long watchId;
1030         Try {
1031                 watchId = static_cast<long>(converter->toLong(arguments[0]));
1032
1033                 if (watchId < 0)
1034                         ThrowMsg(PlatformException, "watchId is wrong (" << watchId << ")");
1035
1036                 addressBook->removeChangeListener(watchId);
1037         } Catch(Exception) {
1038                 LogError("Exception: " << _rethrown_exception.GetMessage());
1039                 JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1040         }
1041
1042         return JSValueMakeUndefined(context);
1043 }
1044
1045 JSValueRef JSAddressBook::getProperty(JSContextRef context,
1046         JSObjectRef object,
1047         JSStringRef jsPropertyName,
1048         JSValueRef* exception)
1049 {
1050     //LogDebug("entered");
1051     ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1052     Try
1053     {
1054         std::string propertyName = converter->toString(jsPropertyName);
1055         IAddressBookPtr addressBook = getPrivData(object);
1056         if (propertyName == TIZEN_ADDRESS_BOOK_TYPE) {
1057             if (IAddressBook::SIMBook == addressBook->getType()) {
1058                 return converter->toJSValueRef(0);
1059             } else {
1060                 return converter->toJSValueRef(1);
1061             }
1062         } else if (propertyName == TIZEN_ADDRESS_BOOK_NAME) {
1063             return converter->toJSValueRef(addressBook->getName());
1064         }
1065     }
1066     Catch(Exception)
1067     {
1068         LogError("error during getting property");
1069     }
1070     return JSValueMakeUndefined(context);
1071 }
1072
1073 } // Contact
1074 } // Tizen1_0
1075 } // TizenApis