2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * @file ConverterMessage.cpp
22 * @author Pawel Misiak (p.misiak@samsung.com)
23 * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
27 #include <dpl/assert.h>
28 #include <Commons/Exception.h>
29 #include <CommonsJavaScript/PrivateObject.h>
30 #include <CommonsJavaScript/Validator.h>
31 #include <CommonsJavaScript/JSUtils.h>
32 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
33 #include "ConverterMessage.h"
34 #include "JSMessage.h"
35 #include "JSMessagePrivateObject.h"
36 #include "JSRecipientArray.h"
37 #include "JSMessagingListener.h"
38 #include <CommonsJavaScript/ScopedJSStringRef.h>
39 #include "JSMessageAttachment.h"
40 #include "JSConversation.h"
41 #include "JSMessageFolder.h"
43 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
44 #include <Tizen/Filesystem/JSFile.h>
48 using namespace WrtDeviceApis::Commons;
49 using namespace WrtDeviceApis::CommonsJavaScript;
52 const char* SEND_PROPERTY_ONSUCCESS = "onsuccess";
53 const char* SEND_PROPERTY_ONMESSAGESENDSUCCESS = "onmessagesendsuccess";
54 const char* SEND_PROPERTY_ONMESSAGESENDERROR = "onmessagesenderror";
60 MessageFunctions ConverterMessage::m_callbackNames[MESSAGING_MULTI_FUNTION_MAX]
62 {"messagesAdded", "messagesUpdated", "messagesRemoved"},
63 {"conversationsAdded", "conversationsUpdated", "conversationsRemoved"},
64 {"foldersAdded", "foldersUpdated", "foldersRemoved"}
67 ConverterMessage::ConverterMessage(JSContextRef context) :
72 ConverterMessage::~ConverterMessage()
76 JSContextRef ConverterMessage::toJSGlobalContext(JSObjectRef arg)
79 WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type* priv =
80 static_cast<WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type*>(JSObjectGetPrivate(
83 LogError("Private object not initialized");
84 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
85 "Private object not initialized");
87 return priv->getContext();
90 JSValueRef ConverterMessage::toJSValueRef(Api::Messaging::FolderType arg)
93 case Api::Messaging::INBOX:
94 return toJSValueRef(messageFolderInbox);
95 case Api::Messaging::OUTBOX:
96 return toJSValueRef(messageFolderOutbox);
97 case Api::Messaging::DRAFTBOX:
98 return toJSValueRef(messageFolderDrafts);
99 case Api::Messaging::SENTBOX:
100 return toJSValueRef(messageFolderSentbox);
102 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "folder not supported");
106 JSValueRef ConverterMessage::toJSValueRef(Api::Messaging::MessageType arg)
109 case Api::Messaging::SMS:
110 return toJSValueRef(messageTypeSms);
111 case Api::Messaging::MMS:
112 return toJSValueRef(messageTypeMms);
113 case Api::Messaging::EMAIL:
114 return toJSValueRef(messageTypeEmail);
116 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
120 JSValueRef ConverterMessage::toJSValueRef(const Api::Messaging::IMessagePtr& arg,
121 Api::Messaging::EventUpdateMessageAnswerReceiver* listener)
123 switch (arg->getMessageType()) {
124 case Api::Messaging::SMS:
125 case Api::Messaging::MMS:
126 case Api::Messaging::EMAIL:
127 return JSMessage::createJSObject(m_context, arg, listener);
130 LogError("unknown type");
131 Throw(WrtDeviceApis::Commons::ConversionException);
135 JSValueRef ConverterMessage::toJSValueRef(
136 const std::vector<Api::Messaging::IMessagePtr>& arg,
137 Api::Messaging::EventUpdateMessageAnswerReceiver* listener)
139 vector<JSValueRef> msgsJS;
140 for (size_t i = 0; i < arg.size(); i++) {
141 msgsJS.push_back(toJSValueRef(arg[i], listener));
143 return toJSValueRef(msgsJS);
146 JSValueRef ConverterMessage::toJSValueRef(const std::vector<Api::Messaging::IConversationPtr>& conversations)
148 vector<JSValueRef> conversationJS;
150 for (size_t i = 0; i < conversations.size(); i++)
152 JSValueRef value = JSConversation::createJSObject(m_context, conversations[i]);
153 conversationJS.push_back(value);
156 return toJSValueRef(conversationJS);
159 JSValueRef ConverterMessage::toJSValueRef(const std::vector<Api::Messaging::IMessageFolderPtr>& messagefolders)
161 vector<JSValueRef> messagefolderJS;
163 for (size_t i = 0; i < messagefolders.size(); i++)
165 JSValueRef value = JSMessageFolder::createJSObject(m_context, messagefolders[i]);
166 messagefolderJS.push_back(value);
169 return toJSValueRef(messagefolderJS);
172 JSValueRef ConverterMessage::toJSValueRef(const Api::Messaging::MessagePriority& arg)
174 switch (arg.getPriority()) {
175 case Api::Messaging::MessagePriority::LOW:
176 return toJSValueRef(false);
178 case Api::Messaging::MessagePriority::NORMAL:
179 return toJSValueRef(false);
181 case Api::Messaging::MessagePriority::HIGH:
182 return toJSValueRef(true);
185 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Unknown priority");
190 JSValueRef ConverterMessage::keyToJSValue(JSValueRef value,
193 JSValueRef retVal = NULL;
196 LogError("jsValue null");
197 Throw(WrtDeviceApis::Commons::ConversionException);
199 JSObjectRef argObj = JSValueToObject(m_context, value, NULL);
200 if (NULL == argObj) {
201 LogError("conversion to jsobject fail");
202 Throw(WrtDeviceApis::Commons::ConversionException);
204 const JSStringRef keyJSStr = JSStringCreateWithUTF8CString(key.c_str());
205 retVal = JSObjectGetProperty(m_context, argObj, keyJSStr, NULL);
206 JSStringRelease(keyJSStr);
207 if (NULL == retVal) {
208 LogWarning("key \"" << key << "\" not found in JSValue map");
210 // return NULL if no key in map
214 Api::Messaging::IMessagePtr ConverterMessage::toIMessage(JSValueRef arg)
216 return toIMessage(toJSObjectRef(arg));
219 Api::Messaging::IMessagePtr ConverterMessage::toIMessage(JSObjectRef arg)
221 LogDebug("message object=" << arg);
223 LogError("Object is null");
224 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
225 "Private object not initialized");
227 Api::Messaging::IMessagePtr retVal;
228 // get private object
229 JSMessagePrivateObject* priv =
230 static_cast<JSMessagePrivateObject*>(JSObjectGetPrivate(arg));
232 LogError("Private object not initialized");
233 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
234 "Private object not initialized");
236 retVal = priv->getObject();
238 LogError("Message private object not initialized");
239 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
240 "Private object not initialized");
245 Api::Messaging::IAttachmentPtr ConverterMessage::toIAttachment(JSValueRef arg)
247 return toIAttachment(toJSObjectRef(arg));
250 Api::Messaging::IAttachmentPtr ConverterMessage::toIAttachment(JSObjectRef arg)
254 LogError("Object is Null");
255 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
258 Api::Messaging::IAttachmentPtr retVal;
259 JSMessageAttachmentPrivate* priv =
260 static_cast<JSMessageAttachmentPrivate*>(JSObjectGetPrivate(arg));
263 LogError("Private object not initialized");
264 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
265 "Private object not initialized");
268 retVal = priv->getObject();
270 LogError("Message private object not initialized");
271 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
272 "Private object not initialized");
277 Api::Messaging::IMessageFolderPtr ConverterMessage::toIMessageFolder(JSValueRef arg)
279 return toIMessageFolder(toJSObjectRef(arg));
282 Api::Messaging::IMessageFolderPtr ConverterMessage::toIMessageFolder(JSObjectRef arg)
286 LogError("Object is Null");
287 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
290 Api::Messaging::IMessageFolderPtr retVal;
291 JSMessageFolderPriv* priv =
292 static_cast<JSMessageFolderPriv*>(JSObjectGetPrivate(arg));
295 LogError("Private object not initialized");
296 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
297 "Private object not initialized");
300 retVal = priv->getObject();
302 LogError("Message private object not initialized");
303 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
304 "Private object not initialized");
309 Api::Messaging::Recipients ConverterMessage::toRecipients(JSValueRef arg)
311 if (JSValueIsObjectOfClass(m_context, arg,
312 JSRecipientArray::getClassRef())) {
313 Api::Messaging::RecipientsPtr recipients =
314 JSRecipientArray::getRecipients(m_context, toJSObjectRef(arg));
316 Throw(WrtDeviceApis::Commons::ConversionException);
320 Api::Messaging::Recipients retVal;
321 // convert JS value to vector of recipient addresses
322 vector<string> recip = toVectorOfStrings(arg);
323 retVal.setRecipients(recip);
327 OnMessagesChanged ConverterMessage::toMessageMultifunctions(JSValueRef argument)
329 OnMessagesChanged result;
330 Validator validator(m_context);
331 JSObjectRef objectCallbacks = toJSObjectRef(argument);
332 std::string callbackName = toString(argument);
337 for (index = 0; index < MESSAGING_MULTI_FUNTION_MAX; index++)
339 ScopedJSStringRef propName(toJSStringRef(m_callbackNames[index].addedFunction));
341 if (JSObjectHasProperty(m_context, objectCallbacks, propName.get()))
343 LogDebug("Callback name :" << m_callbackNames[index].addedFunction << " "
344 << m_callbackNames[index].updatedFunction << " " << m_callbackNames[index].removedFunction);
346 result.messagesAdded = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].addedFunction);
347 result.messagesUpdated = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].updatedFunction);
348 result.messagesRemoved = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].removedFunction);
354 result.functionIndex = index;
356 if ((!validator.isNullOrUndefined(result.messagesAdded) && !validator.isCallback(result.messagesAdded)) ||
357 (!validator.isNullOrUndefined(result.messagesUpdated) && !validator.isCallback(result.messagesUpdated)) ||
358 (!validator.isNullOrUndefined(result.messagesRemoved) && !validator.isCallback(result.messagesRemoved)))
360 LogError("java script call back set error");
361 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
368 std::vector<Api::Messaging::FolderType> ConverterMessage::toVectorOfFolderTypes(
371 return toVectorOfT_(arg, &ConverterMessage::toFolderType, this);
374 Api::Messaging::FolderType ConverterMessage::toFolderType(const JSValueRef& arg)
376 // convert JS value to folder type
377 messageFolders folder = static_cast<messageFolders>(toInt(arg));
379 case messageFolderInbox:
380 return Api::Messaging::INBOX;
381 case messageFolderOutbox:
382 return Api::Messaging::OUTBOX;
383 case messageFolderDrafts:
384 return Api::Messaging::DRAFTBOX;
385 case messageFolderSentbox:
386 return Api::Messaging::SENTBOX;
388 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "folder not supported");
392 Api::Messaging::MessageType ConverterMessage::toMessageType(JSValueRef arg)
394 return toMessageType(toJSObjectRef(arg));
397 Api::Messaging::MessageType ConverterMessage::toMessageType(JSObjectRef arg)
399 // convert JSvalue to message type enum
400 std::string strMsgType = toString(arg);
401 LogDebug("Messasge Type : " << strMsgType);
403 if ( strMsgType.compare("messaging.sms") == 0 )
405 return Api::Messaging::SMS;
407 else if ( strMsgType.compare("messaging.mms") == 0 )
409 return Api::Messaging::MMS;
411 else if ( strMsgType.compare("messaging.email") == 0 )
413 return Api::Messaging::EMAIL;
417 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
422 std::string ConverterMessage::toMessageType( long msgtype )
424 LogDebug("Messasge Type : " << msgtype);
428 case Api::Messaging::SMS:
429 return "messaging.sms";
430 case Api::Messaging::MMS:
431 return "messaging.mms";
432 case Api::Messaging::EMAIL:
433 return "messaging.email";
435 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
439 std::string ConverterMessage::toMessageStatusType( long msgstatus )
441 LogDebug("Messasge Status : " << msgstatus);
445 case Api::Messaging::MESSAGE_STATUS_SENT:
447 case Api::Messaging::MESSAGE_STATUS_SENDING:
449 case Api::Messaging::MESSAGE_STATUS_FAILED:
451 case Api::Messaging::MESSAGE_STATUS_DRAFT:
454 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message status not supported");
458 Api::Messaging::IConversationPtr ConverterMessage::toConversation(const JSValueRef& arg)
460 return JSConversation::getConversation(m_context, arg);
463 std::vector<Api::Messaging::IConversationPtr> ConverterMessage::toVectorOfConversation(const JSValueRef& arg)
465 std::vector<Api::Messaging::IConversationPtr> result;
467 JSObjectRef jsObject = toJSObjectRef(arg);
469 for (std::size_t i = 0; i < JSGetArrayLength(m_context, jsObject); ++i)
471 JSValueRef element = JSGetArrayElement(m_context, jsObject, i);
472 result.push_back(toConversation(element));
478 Api::Messaging::AddressType ConverterMessage::toAddressType(JSValueRef arg)
480 // convert JSvalue to address type enum
481 string addressType = toString(arg);
482 if ("destination" == addressType) {
483 return Api::Messaging::TO_ADDRESS;
484 } else if ("cc" == addressType) {
485 return Api::Messaging::CC_ADDRESS;
486 } else if ("bcc" == addressType) {
487 return Api::Messaging::BCC_ADDRESS;
489 LogError("unknown address type");
490 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
494 Api::Messaging::MessagePriority::Priority ConverterMessage::toMessagePriority(
498 return Api::Messaging::MessagePriority::HIGH;
500 return Api::Messaging::MessagePriority::NORMAL;
504 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
505 Api::Filesystem::INodePtr ConverterMessage::toFilesystemNode(JSValueRef arg)
507 // TODO It doesn't work even when object IS a JS File, not sure what to do?
508 // if (!JSValueIsObjectOfClass(m_context, arg, JSFile::getClassRef())) {
509 // ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a JSFile object.");
512 JSObjectRef attObj = toJSObjectRef(arg);
513 JSFile::PrivateObject* privateObject =
514 static_cast<JSFile::PrivateObject*>(JSObjectGetPrivate(attObj));
515 if (!privateObject) {
516 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
519 Api::Filesystem::INodePtr result = privateObject->getObject();
521 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Node object is NULL.");
528 JSValueRef ConverterMessage::toFunctionOrNull(const JSValueRef& arg)
530 Assert(arg && "Argument is NULL.");
532 if (Validator(m_context).isCallback(arg)) {
534 } else if (!JSValueIsNull(m_context,
535 arg) && !JSValueIsUndefined(m_context, arg)) {
536 ThrowMsg(ConversionException, "Not a function nor JS null.");
541 JSValueRef ConverterMessage::toFunction(const JSValueRef& arg)
543 Assert(arg && "Argument is NULL.");
545 if (Validator(m_context).isCallback(arg)) {
547 } else if (JSValueIsNull(m_context,
548 arg) || JSValueIsUndefined(m_context, arg)) {
549 ThrowMsg(InvalidArgumentException, "JS null passed as function.");
551 ThrowMsg(ConversionException, "Not a function nor JS null.");
555 ConverterMessage::toMessageSendCallback(const JSValueRef& arg)
557 JSObjectRef object = toJSObjectRef(arg);
559 MessageSendCallback result;
560 Validator validator(m_context);
562 result.onSuccess = JSUtils::getJSPropertyOrUndefined(
563 m_context, object, SEND_PROPERTY_ONSUCCESS
565 if (!validator.isNullOrUndefined(result.onSuccess) &&
566 !validator.isCallback(result.onSuccess)) {
567 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
570 result.onMessageSendSuccess = JSUtils::getJSPropertyOrUndefined(
571 m_context, object, SEND_PROPERTY_ONMESSAGESENDSUCCESS
573 if (!validator.isNullOrUndefined(result.onMessageSendSuccess) &&
574 !validator.isCallback(result.onMessageSendSuccess)) {
575 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
578 result.onMessageSendError = JSUtils::getJSPropertyOrUndefined(
579 m_context, object, SEND_PROPERTY_ONMESSAGESENDERROR
581 if (!validator.isNullOrUndefined(result.onMessageSendError) &&
582 !validator.isCallback(result.onMessageSendError)) {
583 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");