Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Account / old / JSAccountService.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 /**
19  * @file        JSAccountService.cpp
20 * @author               Jihwa Park (jh7979.park@samsung.com)
21  * @author      Sangtai Kim
22  * @version     0.1
23  */
24
25 #include <dpl/log/log.h>
26 #include <CommonsJavaScript/PrivateObject.h>
27 #include <CommonsJavaScript/Converter.h>
28 #include <API/Account/IAccountService.h>
29 #include <API/Account/AccountFactory.h>
30 #include <API/Account/IEventCreateAccount.h>
31 #include <API/Account/IEventDeleteAccount.h>
32 #include <API/Account/IEventFindAccounts.h>
33 #include <API/Account/IEventUpdateAccount.h>
34
35
36 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
37 #include <CommonsJavaScript/Utils.h>
38 #include <CommonsJavaScript/Validator.h>
39 #include <CommonsJavaScript/ScopedJSStringRef.h>
40 #include <CommonsJavaScript/SecurityExceptions.h>
41
42
43 #include "JSAccountManager.h"
44 #include "AccountConverter.h"
45 #include "JSAccountService.h"
46 #include "JSAccount.h"
47 #include "plugin_config.h"
48 #include "ResponseDispatcher.h"
49
50 using namespace TizenApis::Api::Account;
51 using namespace WrtDeviceApis::Commons;
52 using namespace WrtDeviceApis::CommonsJavaScript;
53
54 namespace {
55
56 #define TIZEN_ACCOUNT_SERVICE_ATTRIBUTENAME  "AccountService"
57 #define TIZEN_ACCOUNT_SERVICE_PROPERTY_TYPE  "type"
58 #define TIZEN_ACCOUNT_SERVICE_PROPERTY_NAME  "name"
59
60
61 /**
62  * @throw InvalidArgumentException If not a callback nor JS null nor JS undefined.
63  */
64 JSValueRef getFunctionOrNull(JSContextRef ctx,
65         JSValueRef arg)
66 {
67     if (Validator(ctx).isCallback(arg)) {
68                 LogDebug("isCallback");
69         return arg;
70     } else if (!JSValueIsNull(ctx, arg) && !JSValueIsUndefined(ctx, arg)) {
71
72         LogDebug("not Callback");
73         ThrowMsg(InvalidArgumentException, "Not a function nor JS null.");
74     }
75     return NULL;
76 }
77 }
78
79 namespace TizenApis {
80 namespace Tizen1_0 {
81 namespace Account{
82 JSClassDefinition JSAccountService::m_classInfo = {
83     0,
84     kJSClassAttributeNone,
85     TIZEN_ACCOUNT_SERVICE_ATTRIBUTENAME,
86     NULL,
87     m_property,
88     m_function,
89     initialize,
90     finalize,
91     NULL, //HasProperty,
92     NULL, //GetProperty,
93     NULL, //SetProperty,
94     NULL, //DeleteProperty,
95     NULL, //GetPropertyNames,
96     NULL, //CallAsFunction,
97     NULL, //CallAsConstructor,
98     NULL, //HasInstance,
99     NULL //ConvertToType
100 };
101
102 JSStaticValue JSAccountService::m_property[] = {
103     { TIZEN_ACCOUNT_SERVICE_PROPERTY_TYPE, JSAccountService::getPropertyType,
104       NULL, kJSPropertyAttributeReadOnly },
105     { TIZEN_ACCOUNT_SERVICE_PROPERTY_NAME, JSAccountService::getPropertyName,
106       NULL, kJSPropertyAttributeReadOnly },
107     { 0, 0, 0, 0 }
108 };
109
110 JSStaticFunction JSAccountService::m_function[] = {
111     { "createAccount", createAccount, kJSPropertyAttributeNone },
112     { "addAccount", addAccount, kJSPropertyAttributeNone },
113     { "updateAccount", updateAccount, kJSPropertyAttributeNone },
114     { "deleteAccount", deleteAccount, kJSPropertyAttributeNone },
115     { "getAccounts", findAccounts, kJSPropertyAttributeNone },
116
117     { 0, 0, 0 }
118 };
119
120 JSClassRef JSAccountService::m_jsClassRef = JSClassCreate(JSAccountService::getClassInfo());
121
122 void JSAccountService::initialize(JSContextRef context,
123         JSObjectRef object)
124 {
125     LogDebug("entered");
126     AccountServicePrivObject *priv =
127         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(object));
128     if (!priv) {
129         //create default instance
130         LogWarning("create default instance");
131         IAccountServicePtr account =
132             AccountFactory::getInstance().createAccountObject();
133         priv = new AccountServicePrivObject(context, account);
134         if (!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
135             delete priv;
136         }
137     } else {
138         //can be set by JSMakeObject inside getCalendars method
139         LogDebug("private object alrerady exists");
140     }
141 }
142
143 void JSAccountService::finalize(JSObjectRef object)
144 {
145     LogDebug("entered");
146     AccountServicePrivObject *priv =
147         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(object));
148     delete priv;
149 }
150
151 const JSClassRef JSAccountService::getClassRef()
152 {
153     if (!m_jsClassRef) {
154         m_jsClassRef = JSClassCreate(&m_classInfo);
155     }
156     return m_jsClassRef;
157 }
158
159 const JSClassDefinition* JSAccountService::getClassInfo()
160 {
161     return &m_classInfo;
162 }
163
164 JSValueRef JSAccountService::updateAccount(JSContextRef context,
165         JSObjectRef object,
166         JSObjectRef thisObject,
167         size_t argumentCount,
168         const JSValueRef arguments[],
169         JSValueRef* exception)
170 {
171     LogDebug("entered");
172
173     AccountServicePrivObject *privateObject =
174         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(thisObject));
175     assert(privateObject);
176
177 //    AceSecurityStatus status = ACCOUNT_CHECK_ACCESS(privateObject->getContext(),ACCOUNT_FUNCTION_API_UPDATE_ACCOUNT);
178
179     Try
180     {
181         IAccountServicePtr accountservice = getAccountService(context, thisObject, exception);
182
183
184           if (argumentCount != 1) {
185             LogError("Wrong number of parameters.");
186             return JSDOMExceptionFactory::TypeMismatchException.make(context, exception);
187         }
188
189
190
191         if (JSValueIsUndefined(context, arguments[0]) ||JSValueIsNull(context, arguments[0])) {
192             return JSDOMExceptionFactory::InvalidValuesException.make(privateObject->getContext());}
193
194
195        JSObjectRef arg = JSValueToObject(context, arguments[0], exception);
196
197            EventAccountPtr account = JSAccount::getIEvent(arg);
198         if (!JSAccount::validate(context, arg, exception)) {
199             LogError("account parameter contains errors");
200
201             return JSValueMakeNull(context);
202         }
203
204         AccountConverterFactory::ConverterType converter =AccountConverterFactory::getConverter(context);
205         //EventAccountPtr account = converter->toAccount(arguments[0]);
206
207         if (!account) {
208             LogError("updateAccount: Failed to update account");
209
210             return JSDOMExceptionFactory::NotFoundException.make(privateObject->getContext());
211         }
212
213         IEventUpdateAccountPtr dplEvent(new IEventUpdateAccount());
214         dplEvent->setEvent(account);
215         dplEvent->setForSynchronousCall();
216         accountservice->updateAccount(dplEvent);
217
218          if (dplEvent->getResult()) {
219             return JSValueMakeNull(context);
220         } else {
221             LogError("Unknow error occured.");
222             return JSDOMExceptionFactory::UnknownException.make(context, exception);
223         }
224     }
225     Catch(InvalidArgumentException)
226     {
227         LogError("Invalid argument");
228         return JSDOMExceptionFactory::TypeMismatchException.make(context,
229                                                               exception);
230     }
231     Catch(Exception)
232     {
233         LogError("unknow error occured");
234     }
235     return JSValueMakeNull(context);
236 }
237
238 JSValueRef JSAccountService::deleteAccount(JSContextRef context,
239         JSObjectRef object,
240         JSObjectRef thisObject,
241         size_t argumentCount,
242         const JSValueRef arguments[],
243         JSValueRef* exception)
244 {
245     LogDebug("entered");
246     AccountServicePrivObject *privateObject =
247         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(thisObject));
248     assert(privateObject);
249     JSCallbackManagerPtr cbm(NULL);
250
251 //    AceSecurityStatus status = ACCOUNT_CHECK_ACCESS(privateObject->getContext(),ACCOUNT_FUNCTION_API_DELETE_ACCOUNT);
252     Try
253     {
254         IAccountServicePtr accountservice = getAccountService(context, thisObject, exception);
255         if (argumentCount!=1) {
256             LogError("Wrong number of parameters.");
257             return JSDOMExceptionFactory::TypeMismatchException.make(context, exception);
258         }
259
260
261
262         //if not able to convert to int then it won't be found
263         //TODO: Calendar has EventID function. I need to check this later
264         int id = 0;
265         Try
266         {
267
268               AccountConverterFactory::ConverterType converter = AccountConverterFactory::getConverter(context);
269                 id = converter->toInt(converter->toString(arguments[0]));
270         }
271         Catch(Exception)
272         {
273             LogError("invalid value of id parameter, account will not be found");
274              return JSDOMExceptionFactory::NotFoundException.make(privateObject->getContext());
275         }
276         //abstract API use event object as a filter, but only id
277         //attribute is revelant during delete operation.
278         EventAccountPtr account(new EventAccount());
279         account->setID(id);
280         IEventDeleteAccountPtr dplEvent(new IEventDeleteAccount());
281         dplEvent->setEvent(account);
282
283         dplEvent->setForSynchronousCall();
284         accountservice->deleteAccount(dplEvent);
285
286           if (dplEvent->getResult()) {
287             return JSValueMakeNull(context);
288         } else {
289             if (dplEvent->getExceptionCode() == ExceptionCodes::NotFoundException) {
290                 return JSDOMExceptionFactory::NotFoundException.make(context);
291             } else {
292                 return JSDOMExceptionFactory::UnknownException.make(context);
293             }
294         }
295     }
296     Catch(InvalidArgumentException)
297     {
298         LogError("Invalid argument");
299         return JSDOMExceptionFactory::TypeMismatchException.make(context,
300                                                               exception);
301     }
302     Catch(Exception)
303     {
304         LogError("unknow error occured");
305     }
306
307     return JSValueMakeNull(context);
308 }
309
310 JSValueRef JSAccountService::createAccount(JSContextRef context,
311         JSObjectRef object,
312         JSObjectRef thisObject,
313         size_t argumentCount,
314         const JSValueRef arguments[],
315         JSValueRef* exception)
316 {
317     LogDebug("entered");
318
319     AccountServicePrivObject *privateObject =
320         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(thisObject));
321     assert(privateObject);
322
323     Try
324     {
325         // We need to use the global context for the event creation to invoke TZDate functions.
326         JSObjectRef jsObject = JSObjectMake(privateObject->getContext(),
327                                             JSAccount::getClassRef(), NULL);
328         if (jsObject == NULL) {
329             LogError("CreateEvent: failed to create object reference");
330             return JSDOMExceptionFactory::UnknownException.make(context, exception);
331         }
332         if (argumentCount >= 1 &&
333             !JSValueIsUndefined(context, arguments[0]) &&
334             !JSValueIsNull(context, arguments[0])) {
335             //set properties if declared
336             LogDebug("setting properties");
337             AccountConverterFactory::ConverterType converter =
338                 AccountConverterFactory::getConverter(context);
339             EventAccountPtr event = converter->toAccount(arguments[0]);
340
341
342             JSAccount::setIEvent(event, privateObject->getContext(), jsObject);
343         } else {
344
345             //TODO: check if No default value for Account
346               //set default values
347              /*
348               EventAccountPtr account = JSAccount::getIEvent(jsObject);
349             event->setStartTime(std::time(NULL));
350             event->setEndTime(event->getStartTime());
351             event->setStatus(CalendarEvent::CONFIRMED_STATUS);
352             */
353         }
354         return static_cast<JSValueRef>(jsObject);
355     }
356     Catch(ConversionException)
357     {
358         LogError("conversion error");
359         return JSDOMExceptionFactory::InvalidValuesException.make(context,
360                                                                exception);
361     }
362     Catch(Exception)
363     {
364         LogError("error during execution");
365     }
366     return JSDOMExceptionFactory::UnknownException.make(context, exception);
367 }
368
369
370 JSValueRef JSAccountService::addAccount(JSContextRef context,
371         JSObjectRef object,
372         JSObjectRef thisObject,
373         size_t argumentCount,
374         const JSValueRef arguments[],
375         JSValueRef* exception)
376 {
377     LogDebug("entered");
378
379     AccountServicePrivObject *privateObject =
380         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(thisObject));
381     LogDebug("jcpark 1");
382     assert(privateObject);
383     //JSCallbackManagerPtr cbm(NULL);
384    LogDebug("jcpark 2");
385         //TODO: down here!! why?
386      //ACCOUNT_CHECK_ACCESS( privateObject->getContext(),ACCOUNT_FUNCTION_API_ADD_ACCOUNT);
387     Try
388     {
389         LogDebug("1");
390         IAccountServicePtr accountservice = getAccountService(context, thisObject, NULL);
391           LogDebug("2");
392         if (argumentCount != 1) {
393             LogError("Wrong number of parameters.");
394             return JSDOMExceptionFactory::TypeMismatchException.make(context, exception);
395         }
396         LogDebug("3");
397
398                 if (JSValueIsUndefined(context, arguments[0]) ||
399             JSValueIsNull(context, arguments[0])) {
400             return JSDOMExceptionFactory::InvalidValuesException.make(
401                                  privateObject->getContext());
402             return JSValueMakeNull(context);}
403     LogDebug("4");
404               LogDebug("setting properties");
405             AccountConverterFactory::ConverterType converter =
406             AccountConverterFactory::getConverter(context);
407             EventAccountPtr account = converter->toAccount(arguments[0]);
408
409              if (!account) {
410             LogError("Failed to get an event.");
411             return JSDOMExceptionFactory::UnknownException.make(privateObject->getContext());}
412
413                  IEventAddAccountPtr dplEvent(new IEventAddAccount());
414              dplEvent->setEvent(account);
415              dplEvent->setForSynchronousCall();
416              accountservice->addAccount(dplEvent);
417
418                 if (dplEvent->getResult()) {
419             return converter->toJSValueRef(dplEvent->getEvent()->getID());
420              } else {
421             return JSDOMExceptionFactory::UnknownException.make(context, exception);}
422
423     }
424     Catch(InvalidArgumentException)
425     {
426         LogError("Invalid argument");
427         return JSDOMExceptionFactory::TypeMismatchException.make(context,
428                                                               exception);
429     }
430     Catch(Exception)
431     {
432         LogError("Unexpected error during adding account");
433           return JSDOMExceptionFactory::UnknownException.make(privateObject->getContext());
434     }
435     return JSValueMakeNull(context);
436 }
437 JSValueRef JSAccountService::findAccounts(JSContextRef context,
438         JSObjectRef object,
439         JSObjectRef thisObject,
440         size_t argumentCount,
441         const JSValueRef arguments[],
442         JSValueRef* exception)
443 {
444     LogDebug("entered");
445     AccountServicePrivObject *privateObject =
446         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(thisObject));
447     assert(privateObject);
448 //    AceSecurityStatus status = ACCOUNT_CHECK_ACCESS(privateObject->getContext(),ACCOUNT_FUNCTION_API_FIND_ACCOUNTS);
449     JSCallbackManagerPtr cbm(NULL);
450     Try
451     {
452     LogDebug("2");
453         IAccountServicePtr account = getAccountService(context, thisObject, exception);
454         if (argumentCount < 1) {
455             LogError("No callback parameters");
456             return JSDOMExceptionFactory::TypeMismatchException.make(context,
457                                                                   exception);
458         }
459                 LogDebug("3");
460         JSValueRef onError =
461             (argumentCount >
462              1 ? getFunctionOrNull(context, arguments[1]) : NULL);
463         JSContextRef globalContext = privateObject->getContext();
464         LogDebug("4");
465
466         cbm = JSCallbackManager::createObject(globalContext, NULL, onError);
467 //        ASYNC_CBM_ACCESS_STATUS_HANDLER(status, context, cbm);
468
469         Validator validator(context);
470         if (validator.isCallback(arguments[0])) {
471             cbm->setOnSuccess(arguments[0]);
472         } else if (JSValueIsNull(context,
473                                  arguments[0]) ||
474                    JSValueIsUndefined(context, arguments[0])) {
475             cbm->callOnError(JSDOMExceptionFactory::InvalidValuesException.make(
476                                  context));
477             return JSValueMakeNull(context);
478         } else {
479             return JSDOMExceptionFactory::TypeMismatchException.make(context,
480                                                                   exception);
481         }
482         //setup filters
483    /*     EventFilterPtr filter(NULL);
484         if (argumentCount >= 3) {
485             LogDebug("setting some filters");
486             AccountConverterFactory::ConverterType converter =
487                 AccountConverterFactory::getConverter(context);
488             Try
489             {
490                 if (!JSValueIsUndefined(context,
491                                         arguments[2]) &&
492                     !JSValueIsNull(context, arguments[2])) {
493                     filter = converter->toEventFilter(arguments[2]);
494                 }
495             }
496             Catch(InvalidArgumentException)
497             {
498                 LogError("Invalid argument");
499                 filter.Reset();
500             }
501         }*/
502         LogDebug("6");
503         IEventFindAccountsPtr dplEvent(new IEventFindAccounts());
504         dplEvent->setPrivateData(
505             DPL::StaticPointerCast<IEventPrivateData>(cbm));
506         dplEvent->setForAsynchronousCall(
507             &AccountResponseDispatcher::getInstance());
508       //  dplEvent->setFilter(filter);
509         account->findAccounts(dplEvent);
510
511         return makePendingOperation(cbm->getContext(), dplEvent);
512     }
513     Catch(InvalidArgumentException)
514     {
515         return JSDOMExceptionFactory::TypeMismatchException.make(
516                    context, exception);
517     }
518     Catch(ConversionException)
519     {
520         LogError("Invalid argument");
521         return JSDOMExceptionFactory::TypeMismatchException.make(
522                    context, exception);
523     }
524     Catch(Exception)
525     {
526         LogError("unknow error occured");
527     }
528     if (NULL != cbm) {
529         cbm->callOnError(JSDOMExceptionFactory::UnknownException.make(
530                              privateObject->getContext()));
531     }
532     return JSValueMakeNull(context);
533 }
534
535 IAccountServicePtr JSAccountService::getAccountService(JSContextRef ctx,
536         const JSObjectRef object,
537         JSValueRef* exception)
538 {
539     AccountServicePrivObject *priv =
540         static_cast<AccountServicePrivObject*>(JSObjectGetPrivate(object));
541     if (priv) {
542         return priv->getObject();
543     }
544     ThrowMsg(NullPointerException, "Private object is NULL.");
545 }
546
547 JSValueRef JSAccountService::getPropertyName(JSContextRef context,
548         JSObjectRef object,
549         JSStringRef propertyName,
550         JSValueRef* exception)
551 {
552     Try
553     {
554         IAccountServicePtr accountservice = getAccountService(context, object, exception);
555         Converter converter(context);
556         return converter.toJSValueRef(accountservice->getName());
557     }
558     Catch(Exception)
559     {
560         LogError("error during executing a function");
561     }
562     return JSValueMakeUndefined(context);
563 }
564
565 JSValueRef JSAccountService::getPropertyType(JSContextRef context,
566         JSObjectRef object,
567         JSStringRef propertyName,
568         JSValueRef* exception)
569 {
570     Try
571     {
572         IAccountServicePtr accountservice = getAccountService(context, object, exception);
573         int accountserviceType = accountservice->getType();
574         Converter converter(context);
575         switch (accountserviceType) {
576 /*        case IAccountService::TYPE_SIM:
577             return converter.toJSValueRef(
578                        JSAccountManager::TYPE_SIM);
579             break;*/
580         case IAccountService::TYPE_INTERNET:
581             return converter.toJSValueRef(JSAccountManager::TYPE_INTERNET);
582             break;
583         default:
584             LogWarning("invalid type of accountservice");
585             break;
586         }
587     }
588     Catch(Exception)
589     {
590         LogError("error during executing a function");
591     }
592     return JSValueMakeUndefined(context);
593 }
594
595 }
596 }
597 }