Update change log and spec for wrt-plugins-tizen_0.4.70
[framework/web/wrt-plugins-tizen.git] / src / Messaging / JSMessagingService.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "JSMessagingService.h"
19 #include "MessagingController.h"
20 #include <CommonsJavaScript/Converter.h>
21 #include <CommonsJavaScript/Validator.h>
22 #include <CommonsJavaScript/JSUtils.h>
23 #include <CommonsJavaScript/JSCallbackManager.h>
24 #include <CommonsJavaScript/Utils.h>
25 #include <CommonsJavaScript/ScopedJSStringRef.h>
26 #include <CommonsJavaScript/JSPendingOperation.h>
27 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
28 #include <Commons/StringUtils.h>
29
30 #include "ReqReceiverMessage.h"
31 #include <SecurityExceptions.h>
32
33 #include <JSWebAPIErrorFactory.h>
34 #include <ArgumentValidator.h>
35 #include <JSUtil.h>
36
37 #include "MessagingErrorMsg.h"
38 #include "ConverterMessage.h"
39 #include "MessagingListener.h"
40 #include "JSMessagingStorage.h"
41 #include "JSMessage.h"
42 #include "EventSendMessagePrivateData.h" //for send message
43 #include "EventMessagingServicePrivateData.h"
44 #include "MessageAsyncCallbackManager.h"
45 #include "plugin_config_impl.h"
46
47 using namespace std;
48
49 using namespace WrtDeviceApis;
50 using namespace WrtDeviceApis::Commons;
51 using namespace WrtDeviceApis::CommonsJavaScript;
52 using namespace DeviceAPI::Messaging;
53 using namespace DeviceAPI::Common;
54
55 namespace DeviceAPI {
56 namespace Messaging {
57
58 namespace {
59     const char* MESSAGING_SERVICE_ID = "id";
60     const char* MESSAGING_SERVICE_TYPE = "type";
61     const char* MESSAGING_SERVICE_NAME = "name";
62     const char* MESSAGING_SERVICE_MESSAGESTORAGE = "messageStorage";
63 }
64
65 JSClassRef JSMessagingService::m_jsClassRef = NULL;
66
67 JSClassDefinition JSMessagingService::m_classInfo = {
68     0,
69     kJSClassAttributeNone,
70     "MessageService",
71     NULL,
72     m_property,
73     m_function,
74     initialize,
75     finalize,
76     NULL, //hasProperty,
77     JSMessagingService::getProperty, //getProperty,
78     JSMessagingService::setProperty, //setProperty,
79     NULL, //deleteProperty,
80     JSMessagingService::getPropertyNames, //getPropertyNames,
81     NULL,
82     NULL,
83     hasInstance,
84     NULL
85 };
86
87 JSStaticValue JSMessagingService::m_property[] =
88 {
89     { 0, 0, 0, 0 }
90 };
91
92 JSStaticFunction JSMessagingService::m_function[] = {
93     //{ "createMessage",      JSMessagingService::createMessage,       kJSPropertyAttributeNone },
94     { "sendMessage",      JSMessagingService::sendMessage,       kJSPropertyAttributeNone },
95     { "loadMessageBody",      JSMessagingService::loadMessageBody,       kJSPropertyAttributeNone },
96     { "loadMessageAttachment",      JSMessagingService::loadMessageAttachment,       kJSPropertyAttributeNone },
97     { "sync",      JSMessagingService::sync,       kJSPropertyAttributeNone },
98     { "syncFolder",      JSMessagingService::syncFolder,       kJSPropertyAttributeNone },
99     //{ "cancelOperation",   JSMessagingService::cancelOperation,       kJSPropertyAttributeNone },
100     { "stopSync",   JSMessagingService::stopSync,       kJSPropertyAttributeNone },
101     { 0, 0, 0 }
102 };
103
104 const JSClassRef JSMessagingService::getClassRef() {
105     if (!m_jsClassRef) {
106         m_jsClassRef = JSClassCreate(&m_classInfo);
107     }
108     return m_jsClassRef;
109 }
110
111 void JSMessagingService::initialize(JSContextRef context, JSObjectRef object) {
112     LoggerD("creation messaging Service instance");
113 }
114
115 void JSMessagingService::finalize(JSObjectRef object) {
116     LoggerD("finalize messaging instance");
117     //JSMessagingServicePriv *priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(object));
118     JSMessagingServicePriv *priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(object));
119     delete priv;
120 }
121
122 bool JSMessagingService::hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception) {
123     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
124 }
125
126 JSObjectRef JSMessagingService::createJSObject(JSContextRef context, const IMessagingServicePtr &messagingService, const DeviceAPI::Common::SecurityAccessor *securityAccessor)
127 {
128     JSMessagingServicePriv* priv = new JSMessagingServicePriv( context, messagingService);    //make private class.
129     priv->copyAceCheckAccessFunction(securityAccessor);
130     return JSObjectMake(context, getClassRef(), priv);
131 }
132
133 JSValueRef JSMessagingService::getProperty(JSContextRef context,
134         JSObjectRef object,
135         JSStringRef propertyName,
136         JSValueRef* exception)
137 {
138     LoggerD("Entered");
139
140     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(object)); //get private object
141     if (!priv) {
142         LoggerE("Private object not set.");
143         return JSValueMakeUndefined(context);
144     }
145
146     IMessagingServicePtr imessagingService = priv->getObject();
147     try {
148         ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(context);
149
150         if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_TYPE)) {
151             LoggerD("type" << ": " << imessagingService->getType());
152             return JSUtil::toJSValueRef(context, converter->toMessageType(imessagingService->getType()));
153         }
154         else if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_NAME)) {
155             LoggerD("name : " <<  imessagingService->getName());
156             return JSUtil::toJSValueRef(context, imessagingService->getName());
157         }
158         else if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_ID)) {
159             LoggerD("accountId : " <<  imessagingService->getAccountID());
160
161             std::stringstream stream;
162             stream << imessagingService->getAccountID();
163             if (stream.fail()) {
164                 throw DeviceAPI::Common::UnknownException("Couldn't convert e-mail account id");
165             }
166
167             return JSUtil::toJSValueRef(context, stream.str());
168         }
169         else if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_MESSAGESTORAGE)) {
170             JSContextRef l_globalContext = converter->toJSGlobalContext(object);
171             MessagingStoragePrivObjPtr storagePrivObj(new MessagingStoragePrivObj());
172
173             storagePrivObj->m_index = imessagingService->getAccountID();
174             LoggerD("accountId" << ": " <<  storagePrivObj->m_index);
175
176             storagePrivObj->m_type = imessagingService->getType();
177             LoggerD("type" << ": " << storagePrivObj->m_type);
178
179             MessagingStoragePriv *privStorage = new MessagingStoragePriv(l_globalContext, storagePrivObj);
180             privStorage->copyAceCheckAccessFunction(priv);
181
182             return JSObjectMake(l_globalContext, JSMessagingStorage::getClassRef(), privStorage);
183         }
184     }
185     catch (const BasePlatformException& err) {
186         LoggerE(err.getMessage().c_str());
187         return JSValueMakeUndefined(context);
188     }
189     catch (const WrtDeviceApis::Commons::Exception& err) {
190         LoggerE(err.GetMessage().c_str());
191         return JSValueMakeUndefined(context);
192     }
193
194     return NULL;
195 }
196
197 bool JSMessagingService::setProperty(JSContextRef context,
198         JSObjectRef object,
199         JSStringRef propertyName,
200         JSValueRef value,
201         JSValueRef* exception)
202 {
203     LoggerD("Entered");
204
205     if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_ID)) {
206         return true;
207     }
208     else if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_TYPE)) {
209         return true;
210     }
211     else if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_NAME)) {
212         return true;
213     }
214     else if (JSStringIsEqualToUTF8CString(propertyName, MESSAGING_SERVICE_MESSAGESTORAGE)) {
215         return true;
216     }
217
218     return false;
219 }
220
221 void JSMessagingService::getPropertyNames(JSContextRef context,
222         JSObjectRef object,
223         JSPropertyNameAccumulatorRef propertyNames)
224 {
225     LoggerD("Entered");
226     JSStringRef propertyName = NULL;
227
228     propertyName = JSStringCreateWithUTF8CString(MESSAGING_SERVICE_ID);
229     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
230     JSStringRelease(propertyName);
231
232     propertyName = JSStringCreateWithUTF8CString(MESSAGING_SERVICE_TYPE);
233     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
234     JSStringRelease(propertyName);
235
236     propertyName = JSStringCreateWithUTF8CString(MESSAGING_SERVICE_NAME);
237     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
238     JSStringRelease(propertyName);
239
240     propertyName = JSStringCreateWithUTF8CString(MESSAGING_SERVICE_MESSAGESTORAGE);
241     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
242     JSStringRelease(propertyName);
243 }
244
245 #if 0
246 JSValueRef JSMessagingService::createMessage(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
247     const JSValueRef arguments[], JSValueRef* exception)
248 {
249
250     LoggerI("<<<");
251     LoggerD("arumentConunt:" << argumentCount);
252
253     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));
254     if (priv)
255     {
256         //check permission.
257         TIZEN_CHECK_ACCESS(context, exception, priv, MESSAGING_FUNCTION_API_CREATE_MESSAGE);
258
259         try {
260             ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(context);
261             JSContextRef l_globalContext = converter->toJSGlobalContext(thisObject);
262             Validator check(context, exception);
263
264             IMessagingServicePtr imessagingService = priv->getObject();                //get MessagingService.
265             JSValueRef objMsg = NULL;
266
267             MessageType msgType = (MessageType)imessagingService->getType();
268             LoggerI("msgType :" << msgType);
269
270             if (msgType == EMAIL)
271             {
272                 EmailAccountInfo account = imessagingService->getCurrentEmailAccount();
273                 LoggerD("Account Address:" << &account);
274                 objMsg = JSMessage::createJSObject(l_globalContext, account, msgType);        //make message JSValueRef.
275             }
276             else
277             {
278                 objMsg = JSMessage::createJSObject(l_globalContext, msgType);        //make message JSValueRef.
279             }
280
281             //set Properties
282             if ( argumentCount == 1)
283             {
284                 IMessagePtr msg = converter->toIMessage(objMsg) ;
285
286                 if (!msg)
287                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,"platform exception");
288
289                 LoggerD ("##### msg type is " << msg->getId());
290
291                 const ScopedJSStringRef subjectStr(JSStringCreateWithUTF8CString("subject"));
292                 const ScopedJSStringRef toStr(JSStringCreateWithUTF8CString("to"));
293                 const ScopedJSStringRef ccStr(JSStringCreateWithUTF8CString("cc"));
294                 const ScopedJSStringRef bccStr(JSStringCreateWithUTF8CString("bcc"));
295                 const ScopedJSStringRef plainBodyStr(JSStringCreateWithUTF8CString("plainBody"));
296                 const ScopedJSStringRef htmlBodyStr(JSStringCreateWithUTF8CString("htmlBody"));
297                 const ScopedJSStringRef priorityStr(JSStringCreateWithUTF8CString("isHighPriority"));
298
299                 JSObjectRef arg = converter->toJSObjectRef(arguments[0]);
300                 JSValueRef subjectData = JSObjectGetProperty(l_globalContext, arg, subjectStr.get(), NULL);
301                 JSValueRef toData = JSObjectGetProperty(l_globalContext, arg, toStr.get(), NULL);
302                 JSValueRef ccData = JSObjectGetProperty(l_globalContext, arg, ccStr.get(), NULL);
303                 JSValueRef bccData = JSObjectGetProperty(l_globalContext, arg, bccStr.get(), NULL);
304                 JSValueRef plainBodyData = JSObjectGetProperty(l_globalContext, arg, plainBodyStr.get(), NULL);
305                 JSValueRef htmlBodyData = JSObjectGetProperty(l_globalContext, arg, htmlBodyStr.get(), NULL);
306                 JSValueRef priorityData = JSObjectGetProperty(l_globalContext, arg, priorityStr.get(), NULL);
307
308                 //subject
309                  if (!JSValueIsUndefined(l_globalContext, subjectData) )
310                  {
311                      LoggerD ( " Subject : " << converter->toString(subjectData) );
312                     std::string subject = converter->toString(subjectData);
313                      switch (msgType)
314                      {
315                         case MMS:
316                         {
317                             IMmsPtr mms = MessageFactory::convertToMms(msg);
318                             mms->setSubject(subject);
319                             break;
320                         }
321                         case EMAIL:
322                         {
323                             IEmailPtr email = MessageFactory::convertToEmail(msg);
324                             email->setSubject(subject);
325                             break;
326                         }
327                       default:
328                       {
329                             LoggerE("message not supported");
330                             //Throw(WrtDeviceApis::Commons::UnsupportedException);
331                             //break;
332                       }
333                       }
334                  }
335                 //to
336                 if (!JSValueIsUndefined(l_globalContext, toData) )
337                 {
338                     Recipients to = converter->toRecipients(toData);
339                     LoggerD("setting to field, size=" << to.getRecipientSize());
340                     msg->setToRecipients(to);
341                 }
342                 //cc
343                 if (msgType == EMAIL )
344                 {
345                     IEmailPtr email = MessageFactory::convertToEmail(msg);
346                     if (!JSValueIsUndefined(l_globalContext, ccData))
347                     {
348                         Recipients cc = converter->toRecipients(ccData);
349                             email->setCcRecipients(cc);
350                     }
351
352                     if (!JSValueIsUndefined(l_globalContext, bccData))
353                     {
354                         Recipients bcc = converter->toRecipients(bccData);
355                             email->setBccRecipients(bcc);
356                     }
357
358                     if (!JSValueIsUndefined(l_globalContext, htmlBodyData))
359                     {
360                         std::string body = converter->toString(htmlBodyData);
361                         LoggerD("html body : " << body);
362                         email->setHtmlBody(body);
363                     }
364
365                     if (!JSValueIsUndefined(l_globalContext, priorityData))
366                     {
367                         email->setPriority(converter->toMessagePriority(priorityData));
368                     }
369
370                 }
371
372                 if (!JSValueIsUndefined(l_globalContext, plainBodyData) )
373                 {
374                     std::string body = converter->toString(plainBodyData);
375                     LoggerD("plain body  : " << body);
376                     msg->setBody(body);
377                 }
378
379             }
380             return objMsg;
381
382         }
383             Catch(WrtDeviceApis::Commons::InvalidArgumentException) {
384               return JSWebAPIErrorFactory::postException(context, exception,
385                 JSWebAPIErrorFactory::INVALID_VALUES_ERROR, JSMESSAGING_EXCEPTION_MSG_INVALID_ARGUMENT);
386            }
387             Catch(WrtDeviceApis::Commons::ConversionException) {
388               return JSWebAPIErrorFactory::postException(context, exception,
389                 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, JSMESSAGING_EXCEPTION_MSG_TYPE_MISMATCH);
390             }
391
392 //            LoggerI(">>>");
393 //            return JSValueMakeUndefined(context);
394     }
395     else
396     {
397         LoggerD(" Private Object is NULL ");
398         return JSWebAPIErrorFactory::postException(context, exception,
399                 JSWebAPIErrorFactory::NOT_FOUND_ERROR, JSMESSAGING_EXCEPTION_MSG_NOT_FOUND);
400     }
401
402 }
403 #endif
404
405 JSValueRef JSMessagingService::sendMessage(JSContextRef context,
406         JSObjectRef function,
407         JSObjectRef thisObject,
408         size_t argumentCount,
409         const JSValueRef arguments[],
410         JSValueRef* exception)
411 {
412     LoggerD("Entered");
413
414     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));
415     if (!priv) {
416         LoggerE("Private object is NULL.");
417         DeviceAPI::Common::UnknownException err("Private object is NULL.");
418         return JSWebAPIErrorFactory::postException(context, exception, err);
419     }
420
421     //check permission.
422     TIZEN_CHECK_ACCESS(context, exception, priv, MESSAGING_FUNCTION_API_SEND_MESSAGE);
423
424     JSContextRef globalContext = priv->getContext();
425
426     WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(globalContext);
427     WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr recipientCallbackManager;
428
429     callbackManager->setObject(thisObject);
430
431     ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(context);
432
433     try {
434         ArgumentValidator validator(context, argumentCount, arguments);
435
436         // argu 1. Message ( mandatory )
437         JSObjectRef messageArg = validator.toObject(0);
438         if(JSObjectGetPrivate(messageArg) == NULL) {
439             // no private object in argument -> possibly it's an invalid object
440             throw DeviceAPI::Common::TypeMismatchException("Invalid first argument content.");
441         }
442         IMessagePtr msg = converter->toIMessage(messageArg);
443
444         if (msg->getMessageType() != priv->getObject()->getType()) {
445             std::ostringstream str;
446             str << "Message type: "
447                 << msg->getMessageType()
448                 << " doesn't match message service type: "
449                 << priv->getObject()->getType();
450             LoggerW(str.str());
451             throw DeviceAPI::Common::TypeMismatchException(str.str().c_str());
452         }
453
454         // argu 2. Success callback (optional & nullable)
455         JSObjectRef successcb = validator.toFunction(1, true);
456         callbackManager->setOnSuccess(successcb);
457
458         // argu 3. error callback (optional & nullable)
459         callbackManager->setOnError(validator.toFunction(2, true));
460
461         //create PrivateData
462         EventMessagingServicePrivateDataPtr privateData( new EventMessagingServicePrivateData(callbackManager, recipientCallbackManager) );
463
464         EventMessagingServicePtr event(new EventMessagingService());
465
466         IMessagingServicePtr imessagingService = priv->getObject();
467
468         event->opId = imessagingService->createOpId(MESSAGING_SERVICE_OP_SEND_MESSAGE);
469         event->setEventType(MESSAGING_SERVICE_EVENT_TYPE_SEND_MESSAGE);
470         event->m_message = msg;
471         imessagingService->setMessageToOpId( event->opId, event->m_message);
472         event->store = true; //always store message in sendbox after send , email Type.
473         event->m_messagingService = imessagingService;
474         event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privateData));
475         event->setForAsynchronousCall(&MessagingController::getInstance());
476
477         ReqReceiverMessageSingleton::Instance().sendMessage(event); //send message
478         MessageAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, globalContext);
479     }
480     catch(const BasePlatformException& err) {
481         LoggerE(err.getMessage().c_str());
482         return JSWebAPIErrorFactory::postException(context, exception, err);
483     }
484     catch (const WrtDeviceApis::Commons::NullPointerException& exc) {
485         LoggerE(exc.GetMessage().c_str());
486         DeviceAPI::Common::TypeMismatchException err(exc.GetMessage().c_str());
487         return JSWebAPIErrorFactory::postException(context, exception, err);
488     }
489     catch (const WrtDeviceApis::Commons::Exception& exc) {
490         LoggerE(exc.GetMessage().c_str());
491         DeviceAPI::Common::UnknownException err(exc.GetMessage().c_str());
492         return JSWebAPIErrorFactory::postException(context, exception, err);
493     }
494
495     return JSValueMakeUndefined(context);
496 }
497
498 JSValueRef JSMessagingService::loadMessageBody(JSContextRef context,
499         JSObjectRef function,
500         JSObjectRef thisObject,
501         size_t argumentCount,
502         const JSValueRef arguments[],
503         JSValueRef* exception)
504 {
505     LoggerD("Entered");
506
507     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));
508     if (!priv) {
509         LoggerE("Private object is NULL.");
510         DeviceAPI::Common::UnknownException err("Private object is NULL.");
511         return JSWebAPIErrorFactory::postException(context, exception, err);
512     }
513
514     //check permission.
515     TIZEN_CHECK_ACCESS(context, exception, priv, MESSAGING_FUNCTION_API_LOAD_MESSAGE_BODY);
516
517     JSContextRef globalContext = priv->getContext(); //create global Context
518
519     WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(globalContext);
520     callbackManager->setObject(thisObject);
521
522     ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(globalContext); //create converter
523
524     try {
525         ArgumentValidator validator(context, argumentCount, arguments);
526
527         // argu 1. Message ( mandatory )
528         JSObjectRef messageArg = validator.toObject(0);
529         if(JSObjectGetPrivate(messageArg) == NULL) {
530             // no private object in argument -> possibly it's an invalid object
531             throw DeviceAPI::Common::TypeMismatchException("Invalid first argument content.");
532         }
533         IMessagePtr msg = converter->toIMessage(messageArg);
534
535         if (msg->getMessageType() != priv->getObject()->getType()) {
536             std::ostringstream str;
537             str << "Message type: "
538                 << msg->getMessageType()
539                 << " doesn't match message service type: "
540                 << priv->getObject()->getType();
541             LoggerW(str.str());
542             throw DeviceAPI::Common::TypeMismatchException(str.str().c_str());
543         }
544
545         // argu 2. Success callback
546         callbackManager->setOnSuccess(validator.toFunction(1));
547
548         // argu 3. error callback (optional & nullable)
549         callbackManager->setOnError(validator.toFunction(2, true));
550
551         //create event
552         EventMessagingServicePrivateDataPtr privateData( new EventMessagingServicePrivateData(callbackManager) );
553         EventMessagingServicePtr event(new EventMessagingService());
554         event->m_message = msg;
555
556         if ( event->m_message )
557         {
558             int msgType = event->m_message->getMessageType();
559
560             if (msgType == EMAIL)
561             {
562                 IEmailPtr email = MessageFactory::convertToEmail(event->m_message);
563             }
564             privateData->setMessageJSValueRef(arguments[0]); //set Message JSValueRef.
565         }
566         LoggerI(" Checked Message Type " );
567
568         IMessagingServicePtr imessagingService = priv->getObject();
569         int opId = imessagingService->createOpId(MESSAGING_SERVICE_OP_DOWNLOAD_BODY);
570         LoggerD("Operation ID is = " << opId);
571
572         event->opId = opId;
573         imessagingService->setMessageToOpId(opId, event->m_message);
574         imessagingService->setEventToOpId(event->opId, event);
575         event->m_messagingService = imessagingService;
576
577         event->setEventType(MESSAGING_SERVICE_EVENT_TYPE_LOAD_MESSAGE_BODY);
578         event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privateData));
579         event->setForAsynchronousCall(&MessagingController::getInstance());
580
581         ReqReceiverMessageSingleton::Instance().loadMessageBody(event); //load message Body
582         MessageAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, globalContext);
583     }
584     catch(const BasePlatformException& err) {
585         LoggerE(err.getMessage().c_str());
586         return JSWebAPIErrorFactory::postException(context, exception, err);
587     }
588     catch (const WrtDeviceApis::Commons::NullPointerException& exc) {
589         LoggerE(exc.GetMessage().c_str());
590         DeviceAPI::Common::TypeMismatchException err(exc.GetMessage().c_str());
591         return JSWebAPIErrorFactory::postException(context, exception, err);
592     }
593     catch (const WrtDeviceApis::Commons::Exception& exc) {
594         LoggerE(exc.GetMessage().c_str());
595         DeviceAPI::Common::UnknownException err(exc.GetMessage().c_str());
596         return JSWebAPIErrorFactory::postException(context, exception, err);
597     }
598
599     return JSValueMakeUndefined(context);
600 }
601
602 JSValueRef JSMessagingService::loadMessageAttachment(JSContextRef context,
603         JSObjectRef function,
604         JSObjectRef thisObject,
605         size_t argumentCount,
606         const JSValueRef arguments[],
607         JSValueRef* exception)
608 {
609     LoggerD("Entered");
610
611     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));
612     if (!priv) {
613         LoggerE("Private object is NULL.");
614         DeviceAPI::Common::UnknownException err("Private object is NULL.");
615         return JSWebAPIErrorFactory::postException(context, exception, err);
616     }
617
618     //check permission.
619     TIZEN_CHECK_ACCESS(context, exception, priv, MESSAGING_FUNCTION_API_LOAD_MESSAGE_ATTACHMENT);
620
621     JSContextRef globalContext = priv->getContext(); //create global Context
622
623     WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(globalContext);
624     callbackManager->setObject(thisObject);
625
626     ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(globalContext); //create converter
627
628     try {
629         ArgumentValidator validator(context, argumentCount, arguments);
630
631         //argu 1. Attachment (mandatory)
632         JSObjectRef attachmentArg = validator.toObject(0);
633         if(JSObjectGetPrivate(attachmentArg) == NULL) {
634             // no private object in argument -> possibly it's an invalid object
635             throw DeviceAPI::Common::TypeMismatchException("Invalid first argument content.");
636         }
637         IAttachmentPtr iAttchmentPtr = converter->toIAttachment(attachmentArg);
638
639         // argu 2. Success callback
640         callbackManager->setOnSuccess(validator.toFunction(1));
641
642         // argu 3. error callback (optional & nullable)
643         callbackManager->setOnError(validator.toFunction(2, true));
644
645         EventMessagingServicePrivateDataPtr privateData( new EventMessagingServicePrivateData(callbackManager) );
646         if (!privateData) {
647             throw DeviceAPI::Common::UnknownException("Private data is NULL.");
648         }
649
650         LoggerI("iAttchmentPtr->getDownloaded() : " << iAttchmentPtr->getDownloaded());
651         if(iAttchmentPtr->getDownloaded() > 0)
652         {
653             callbackManager->callOnSuccess(converter->toJSValueRef(iAttchmentPtr));
654             return JSValueMakeUndefined(context);
655         }
656
657         EventMessagingServicePtr event(new EventMessagingService());     //create event
658         event->setEventType(MESSAGING_SERVICE_EVENT_TYPE_LOAD_MESSAGE_ATTACHMENT);
659         event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privateData));
660         event->setForAsynchronousCall(&MessagingController::getInstance());
661
662         event->m_attachment = iAttchmentPtr;
663         event->m_message = event->m_attachment->getMessage();
664
665         privateData->setMessageJSValueRef(arguments[0]); //set attachment JSValueRef.
666
667         IMessagingServicePtr imessagingService = priv->getObject();
668         if (imessagingService)
669         {
670             int opId = imessagingService->createOpId(MESSAGING_SERVICE_OP_DOWNLOAD_ATTACHMENT);
671             LoggerD("Operation ID is = " << opId);
672
673             event->opId = opId;
674             imessagingService->setMessageToOpId(opId, event->m_message);
675             imessagingService->setEventToOpId(event->opId, event);
676             event->m_messagingService = imessagingService;
677
678             ReqReceiverMessageSingleton::Instance().loadMessageAttachment(event); //load message Attachment
679             MessageAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, globalContext);
680         }
681         else
682         {
683             throw DeviceAPI::Common::UnknownException("MessagingService not found.");
684         }
685     }
686     catch(const BasePlatformException& err) {
687         LoggerE(err.getMessage().c_str());
688         return JSWebAPIErrorFactory::postException(context, exception, err);
689     }
690     catch (const WrtDeviceApis::Commons::Exception& exc) {
691         LoggerE(exc.GetMessage().c_str());
692         DeviceAPI::Common::UnknownException err(exc.GetMessage().c_str());
693         return JSWebAPIErrorFactory::postException(context, exception, err);
694     }
695
696     return JSValueMakeUndefined(context);
697 }
698
699 JSValueRef JSMessagingService::sync(JSContextRef context, JSObjectRef function, JSObjectRef thisObject,
700             size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
701 {
702     LoggerD("Entered");
703
704     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));
705     if (!priv) {
706         LoggerE("Private object is NULL.");
707         DeviceAPI::Common::UnknownException err("Private object is NULL.");
708         return JSWebAPIErrorFactory::postException(context, exception, err);
709     }
710
711     //check permission.
712     TIZEN_CHECK_ACCESS(context, exception, priv, MESSAGING_FUNCTION_API_SYNC);
713
714     JSContextRef globalContext = priv->getContext(); //get global Context
715
716     WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(globalContext);
717     callbackManager->setObject(thisObject);
718
719     ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(globalContext); //create converter
720
721     try {
722         ArgumentValidator validator(context, argumentCount, arguments);
723
724         // argu 1. Success callback (optional & nullable)
725         callbackManager->setOnSuccess(validator.toFunction(0, true));
726
727         // argu 2. error callback (optional & nullable)
728         callbackManager->setOnError(validator.toFunction(1, true));
729
730         // argu 3. limit ( optional )
731         int limit = validator.toLong(2, true, -1); //sync limit
732         LoggerD("limit : " << limit);
733
734         IMessagingServicePtr imessagingService = priv->getObject(); //get MessagingService.
735
736         MessageType msgType = (MessageType)imessagingService->getType();
737         LoggerI("msgType :" << msgType);
738         if (msgType != EMAIL) {
739             std::string errMessage = converter->toMessageType(imessagingService->getType()) + " not supported";
740             throw DeviceAPI::Common::NotSupportedException(errMessage.c_str());
741         }
742
743         EventMessagingServicePrivateDataPtr privateData( new EventMessagingServicePrivateData(callbackManager) );
744         EventMessagingServicePtr event(new EventMessagingService()); //create event
745
746         event->opId = imessagingService->createOpId(MESSAGING_SERVICE_OP_SYNC);
747         event->m_sync_account_id = imessagingService->getAccountID() ;
748         event->m_sync_limit = limit;
749         event->m_messagingService = imessagingService;
750         imessagingService->setEventToOpId(event->opId, event);
751
752         event->setEventType(MESSAGING_SERVICE_EVENT_TYPE_SYNC);
753         event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privateData));
754         event->setForAsynchronousCall(&MessagingController::getInstance());
755
756         ReqReceiverMessageSingleton::Instance().sync(event); // sync with an external mail server
757         MessageAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, globalContext);
758
759         return JSUtil::toJSValueRef(context, (long int)event->opId);
760     }
761     catch(const BasePlatformException& err) {
762         LoggerE(err.getMessage().c_str());
763         return JSWebAPIErrorFactory::postException(context, exception, err);
764     }
765     catch (const WrtDeviceApis::Commons::Exception& exc) {
766         LoggerE(exc.GetMessage().c_str());
767         DeviceAPI::Common::UnknownException err(exc.GetMessage().c_str());
768         return JSWebAPIErrorFactory::postException(context, exception, err);
769     }
770 }
771
772 JSValueRef JSMessagingService::syncFolder(JSContextRef context, JSObjectRef function, JSObjectRef thisObject,
773             size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
774 {
775     LoggerD("Entered");
776
777     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));
778     if (!priv) {
779         LoggerE("Private object is NULL.");
780         DeviceAPI::Common::UnknownException err("Private object is NULL.");
781         return JSWebAPIErrorFactory::postException(context, exception, err);
782     }
783
784     //check permission.
785     TIZEN_CHECK_ACCESS(context, exception, priv, MESSAGING_FUNCTION_API_SYNC_FOLDER);
786
787     JSContextRef globalContext = priv->getContext(); //get global Context
788
789     WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(globalContext);
790     callbackManager->setObject(thisObject);
791
792     ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(globalContext); //create converter
793
794     try {
795         ArgumentValidator validator(context, argumentCount, arguments);
796
797         // argu 1. Folder (mandatory)
798         JSObjectRef folderArg = validator.toObject(0);
799         if(JSObjectGetPrivate(folderArg) == NULL) {
800             // no private object in argument -> possibly it's an invalid object
801             throw DeviceAPI::Common::TypeMismatchException("Invalid first argument content.");
802         }
803         IMessageFolderPtr folder = converter->toIMessageFolder(folderArg);
804
805         // argu 2. Success callback (optional & nullable)
806         callbackManager->setOnSuccess(validator.toFunction(1, true));
807
808         // argu 3. error callback (optional & nullable)
809         callbackManager->setOnError(validator.toFunction(2, true));
810
811         // argu 4. limit ( optional )
812         int limit = validator.toLong(3, true, -1); //sync limit
813         LoggerD("limit : " << limit);
814
815         IMessagingServicePtr imessagingService = priv->getObject(); //get MessagingService.
816
817         MessageType msgType = (MessageType)imessagingService->getType();
818         LoggerI("msgType :" << msgType);
819         if (msgType != EMAIL) {
820             std::string errMessage = converter->toMessageType(imessagingService->getType()) + " not supported";
821             throw DeviceAPI::Common::NotSupportedException(errMessage.c_str());
822         }
823
824         EventMessagingServicePtr event(new EventMessagingService()); //create event
825         EventMessagingServicePrivateDataPtr privateData( new EventMessagingServicePrivateData(callbackManager) );
826
827         if ( folder )
828         {
829             event->m_folder_name = folder->getPath(); //it will be changed to the folder ptr
830             event->m_sync_folder_id = folder->getId(); //it will be changed to the folder ptr
831         }
832
833         LoggerD("folderName : " << event->m_folder_name);
834         event->opId = imessagingService->createOpId(MESSAGING_SERVICE_OP_SYNC_FOLDER);
835         event->m_sync_account_id = imessagingService->getAccountID() ;
836         event->m_sync_limit = limit;
837         event->m_messagingService = imessagingService;
838         imessagingService->setEventToOpId(event->opId, event);
839
840         event->setEventType(MESSAGING_SERVICE_EVENT_TYPE_SYNC_FOLDER);
841         event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privateData));
842         event->setForAsynchronousCall(&MessagingController::getInstance());
843
844         ReqReceiverMessageSingleton::Instance().syncFolder(event); //load message Body
845         MessageAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, globalContext);
846
847         return JSUtil::toJSValueRef(context, (long int)event->opId);
848     }
849     catch(const BasePlatformException& err) {
850         LoggerE(err.getMessage().c_str());
851         return JSWebAPIErrorFactory::postException(context, exception, err);
852     }
853     catch (const WrtDeviceApis::Commons::NullPointerException& exc) {
854         LoggerE(exc.GetMessage().c_str());
855         DeviceAPI::Common::TypeMismatchException err(exc.GetMessage().c_str());
856         return JSWebAPIErrorFactory::postException(context, exception, err);
857     }
858     catch (const WrtDeviceApis::Commons::Exception& exc) {
859         LoggerE(exc.GetMessage().c_str());
860         DeviceAPI::Common::UnknownException err(exc.GetMessage().c_str());
861         return JSWebAPIErrorFactory::postException(context, exception, err);
862     }
863 }
864 #if 0
865 JSValueRef JSMessagingService::cancelOperation(JSContextRef context, JSObjectRef function, JSObjectRef thisObject,
866             size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
867 {
868     LoggerD("entered");
869
870     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));    //get private object
871
872     if (priv)
873     {
874         IMessagingServicePtr imessagingService = priv->getObject();
875         Try
876         {
877             LoggerI(">>> argument count : " << argumentCount);
878
879             if ( argumentCount == 1 && !Validator(context).isCallback(arguments[0]))
880             {
881                 ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(context);
882                 MessageType msgType = (MessageType)imessagingService->getType();
883                 LoggerI("msgType :" << msgType);
884
885                 int opId = converter->toLong( arguments[0] );    //Fetch operation ID
886                 int handle = imessagingService->getHandleFromOpId(opId);
887                 if ( handle < 0 )
888                 {
889                     ThrowMsg(WrtDeviceApis::Commons::NotFoundException,"Operation ID Not found");
890                 }
891
892                 int opType = imessagingService->getOpTypeFromOpId(opId);
893                 LoggerI("operation ID :" << opId << " operation Type : "  << opType);
894
895                 if ( opType == MESSAGING_SERVICE_OP_SEND_MESSAGE)
896                 {
897                     IMessagePtr msg = imessagingService->getMessageFromOpId(opId);
898                     if (msg)
899                     {
900                         LoggerD("Call Cancel Function");
901                         msg->sendCancel(handle);
902                         imessagingService->deleteOpId(opId);
903                     }
904                 }
905                 else
906                 {    //for email.
907                     if (msgType == EMAIL)
908                     {
909                         IMessagePtr msg = imessagingService->getMessageFromOpId(opId);
910                         IEmailPtr email = MessageFactory::convertToEmail(msg);
911
912                         if ( opType == MESSAGING_SERVICE_OP_DOWNLOAD_BODY )
913                         {
914                             LoggerD("Cancel Download Body , handle = " << handle);
915                             email->downloadBodyCancel(handle);
916                         }
917                         else if ( opType == MESSAGING_SERVICE_OP_DOWNLOAD_ATTACHMENT)
918                         {
919                             LoggerD("Cancel Download Attachment , handle = " << handle);
920                             email->downloadAttachmentCancel(handle);
921                         }
922                         else if (  opType == MESSAGING_SERVICE_OP_SYNC )
923                         {
924                             LoggerD("Cancel Sync , handle = " << handle);
925                             imessagingService->syncCancel(handle);
926                         }
927                         else if ( opType == MESSAGING_SERVICE_OP_SYNC_FOLDER )
928                         {
929                             LoggerD("Cancel Sync Folder, handle = " << handle);
930                             imessagingService->syncFolderCancel(handle);
931                         }
932                         imessagingService->deleteOpId(opId);
933                     }
934                     else
935                     {
936                         ThrowMsg(WrtDeviceApis::Commons::UnsupportedException, "Operation Type is mismatched");
937                     }
938                 }
939
940             }
941             else
942             {
943                 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException,"invalid argument exception");
944             }
945
946         }
947         Catch (WrtDeviceApis::Commons::InvalidArgumentException){
948             LoggerE("Exception: " << _rethrown_exception.GetMessage());
949             return JSWebAPIErrorFactory::postException(context, exception,
950                 JSWebAPIErrorFactory::INVALID_VALUES_ERROR, JSMESSAGING_EXCEPTION_MSG_INVALID_ARGUMENT);
951         }
952         Catch (WrtDeviceApis::Commons::NotFoundException){
953             LoggerE("Exception: " << _rethrown_exception.GetMessage());
954             return JSWebAPIErrorFactory::postException(context, exception,
955                 JSWebAPIErrorFactory::NOT_FOUND_ERROR, JSMESSAGING_EXCEPTION_MSG_NOT_FOUND);
956         }
957         Catch (WrtDeviceApis::Commons::UnsupportedException){
958             LoggerE("Exception: " << _rethrown_exception.GetMessage());
959             return JSWebAPIErrorFactory::postException(context, exception,
960                 JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, JSMESSAGING_EXCEPTION_MSG_NOT_SUPPORTED);
961         }
962         Catch (WrtDeviceApis::Commons::Exception){
963             LoggerE("Exception: " << _rethrown_exception.GetMessage());
964             return JSWebAPIErrorFactory::postException(context, exception,
965                 JSWebAPIErrorFactory::UNKNOWN_ERROR, JSMESSAGING_EXCEPTION_MSG_UNKNOWN);
966         }
967
968     }
969     else
970     {
971         LoggerD(" Private Object is NULL ");
972         return JSWebAPIErrorFactory::postException(context, exception,
973                     JSWebAPIErrorFactory::NOT_FOUND_ERROR, JSMESSAGING_EXCEPTION_MSG_NOT_FOUND);
974     }
975
976     LoggerD(">>>");
977     return JSValueMakeUndefined(context);
978 }
979 #endif
980
981 JSValueRef JSMessagingService::stopSync(JSContextRef context, JSObjectRef function, JSObjectRef thisObject,
982             size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
983 {
984     LoggerD("Entered");
985
986     JSMessagingServicePriv* priv = static_cast<JSMessagingServicePriv*>(JSObjectGetPrivate(thisObject));
987     if (!priv) {
988         LoggerE("Private object is NULL.");
989         DeviceAPI::Common::UnknownException err("Private object is NULL.");
990         return JSWebAPIErrorFactory::postException(context, exception, err);
991     }
992
993     try {
994         ArgumentValidator validator(context, argumentCount, arguments);
995
996         // argu 1. opId
997         int opId = validator.toLong(0);
998         LoggerD("opId : " << opId);
999
1000         ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(context);
1001
1002         IMessagingServicePtr imessagingService = priv->getObject();
1003         MessageType msgType = (MessageType)imessagingService->getType();
1004         LoggerI("msgType :" << msgType);
1005         if (msgType != EMAIL) {
1006             std::string errMessage = converter->toMessageType(imessagingService->getType()) + " not supported";
1007             throw DeviceAPI::Common::NotSupportedException(errMessage.c_str());
1008         }
1009
1010         int handle = imessagingService->getHandleFromOpId(opId);
1011         if ( handle < 0 )
1012         {
1013             LoggerI("operation ID is not found : " << opId);
1014             return JSValueMakeUndefined(context);
1015         }
1016
1017         int opType = imessagingService->getOpTypeFromOpId(opId);
1018         LoggerI("operation ID :" << opId << " operation Type : "  << opType);
1019
1020         if (  opType == MESSAGING_SERVICE_OP_SYNC )
1021         {
1022             LoggerD("Cancel Sync , handle = " << handle);
1023             imessagingService->syncCancel(handle);
1024         }
1025         else if ( opType == MESSAGING_SERVICE_OP_SYNC_FOLDER )
1026         {
1027             LoggerD("Cancel Sync Folder, handle = " << handle);
1028             imessagingService->syncFolderCancel(handle);
1029         }
1030         else
1031         {
1032             throw DeviceAPI::Common::UnknownException("Operation Type is mismatched");
1033         }
1034
1035         //call error callback.
1036         EventMessagingServicePtr event = imessagingService->getEventFromOpId(opId);
1037         if (event)
1038         {
1039             LoggerD("get callback Manager");
1040             EventMessagingServicePrivateDataPtr privateData =
1041             DPL::StaticPointerCast<EventMessagingServicePrivateData>(event->getPrivateData());
1042
1043             WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr callbackManager = privateData->getCallbackManager(); //get callback manager
1044             JSContextRef globalContext = callbackManager->getContext();
1045             if (callbackManager)
1046             {
1047                 JSValueRef error = NULL;
1048                 LoggerD("call error callback.");
1049                 error = JSWebAPIErrorFactory::makeErrorObject(globalContext, JSWebAPIErrorFactory::ABORT_ERROR, JSMESSAGING_EXCEPTION_MSG_ABORT_ERROR);
1050                 callbackManager->callOnError(error);
1051             }
1052         }
1053
1054         imessagingService->deleteOpId(opId);
1055     }
1056     catch(const BasePlatformException& err) {
1057         LoggerE(err.getMessage().c_str());
1058         return JSWebAPIErrorFactory::postException(context, exception, err);
1059     }
1060     catch (const WrtDeviceApis::Commons::Exception& exc) {
1061         LoggerE(exc.GetMessage().c_str());
1062         DeviceAPI::Common::UnknownException err(exc.GetMessage().c_str());
1063         return JSWebAPIErrorFactory::postException(context, exception, err);
1064     }
1065
1066     return JSValueMakeUndefined(context);
1067 }
1068
1069
1070 }
1071 }
1072