2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dpl/assert.h>
19 #include <Commons/Exception.h>
20 #include <CommonsJavaScript/PrivateObject.h>
21 #include <CommonsJavaScript/Validator.h>
22 #include <CommonsJavaScript/JSUtils.h>
23 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
24 #include "ConverterMessage.h"
25 #include "JSMessage.h"
26 #include "JSMessagePrivateObject.h"
27 #include "JSRecipientArray.h"
28 #include "MessagingListener.h"
29 #include <CommonsJavaScript/ScopedJSStringRef.h>
30 #include "JSMessageAttachment.h"
31 #include "JSConversation.h"
32 #include "JSMessageFolder.h"
34 #include <JSWebAPIError.h>
36 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
41 using namespace WrtDeviceApis::Commons;
42 using namespace WrtDeviceApis::CommonsJavaScript;
45 const char* SEND_PROPERTY_ONSUCCESS = "onsuccess";
46 const char* SEND_PROPERTY_ONMESSAGESENDSUCCESS = "onmessagesendsuccess";
47 const char* SEND_PROPERTY_ONMESSAGESENDERROR = "onmessagesenderror";
53 MessageFunctions ConverterMessage::m_callbackNames[MESSAGING_MULTI_FUNTION_MAX]
55 {"messagesadded", "messagesupdated", "messagesremoved"},
56 {"conversationsadded", "conversationsupdated", "conversationsremoved"},
57 {"foldersadded", "foldersupdated", "foldersremoved"}
60 ConverterMessage::ConverterMessage(JSContextRef context) :
65 ConverterMessage::~ConverterMessage()
69 JSContextRef ConverterMessage::toJSGlobalContext(JSObjectRef arg)
72 WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type* priv =
73 static_cast<WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type*>(JSObjectGetPrivate(
76 LogError("Private object not initialized");
77 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
78 "Private object not initialized");
80 return priv->getContext();
83 JSValueRef ConverterMessage::toJSValueRef(FolderType arg)
87 return toJSValueRef(messageFolderInbox);
89 return toJSValueRef(messageFolderOutbox);
91 return toJSValueRef(messageFolderDrafts);
93 return toJSValueRef(messageFolderSentbox);
95 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "folder not supported");
99 JSValueRef ConverterMessage::toJSValueRef(MessageType arg)
103 return toJSValueRef(messageTypeSms);
105 return toJSValueRef(messageTypeMms);
107 return toJSValueRef(messageTypeEmail);
109 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
113 JSValueRef ConverterMessage::toJSValueRef(const IMessagePtr& arg)
115 switch (arg->getMessageType()) {
120 return JSMessage::createJSObject(m_context, arg);
123 LogError("unknown type");
124 Throw(WrtDeviceApis::Commons::ConversionException);
128 JSValueRef ConverterMessage::toJSValueRef(const IMessagePtr& arg,
129 EventUpdateMessageAnswerReceiver* listener)
131 switch (arg->getMessageType()) {
136 return JSMessage::createJSObject(m_context, arg, listener);
139 LogError("unknown type");
140 Throw(WrtDeviceApis::Commons::ConversionException);
144 JSValueRef ConverterMessage::toJSValueRef(
145 const std::vector<IMessagePtr>& arg,
146 EventUpdateMessageAnswerReceiver* listener)
148 vector<JSValueRef> msgsJS;
149 for (size_t i = 0; i < arg.size(); i++) {
150 msgsJS.push_back(toJSValueRef(arg[i], listener));
152 return toJSValueRef(msgsJS);
155 JSValueRef ConverterMessage::toJSValueRef(const std::vector<IConversationPtr>& conversations)
157 vector<JSValueRef> conversationJS;
159 for (size_t i = 0; i < conversations.size(); i++)
161 JSValueRef value = JSConversation::createJSObject(m_context, conversations[i]);
162 conversationJS.push_back(value);
165 return toJSValueRef(conversationJS);
168 JSValueRef ConverterMessage::toJSValueRef(const std::vector<IMessageFolderPtr>& messagefolders)
170 vector<JSValueRef> messagefolderJS;
172 for (size_t i = 0; i < messagefolders.size(); i++)
174 JSValueRef value = JSMessageFolder::createJSObject(m_context, messagefolders[i]);
175 messagefolderJS.push_back(value);
178 return toJSValueRef(messagefolderJS);
181 JSValueRef ConverterMessage::toJSValueRef(const MessagePriority& arg)
183 switch (arg.getPriority()) {
184 case MessagePriority::LOW:
185 return toJSValueRef(false);
187 case MessagePriority::NORMAL:
188 return toJSValueRef(false);
190 case MessagePriority::HIGH:
191 return toJSValueRef(true);
194 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Unknown priority");
199 JSValueRef ConverterMessage::toJSValueRef(const IAttachmentPtr& arg)
201 return JSMessageAttachment::createJS(m_context, arg);
204 JSValueRef ConverterMessage::keyToJSValue(JSValueRef value,
207 JSValueRef retVal = NULL;
210 LogError("jsValue null");
211 Throw(WrtDeviceApis::Commons::ConversionException);
213 JSObjectRef argObj = JSValueToObject(m_context, value, NULL);
214 if (NULL == argObj) {
215 LogError("conversion to jsobject fail");
216 Throw(WrtDeviceApis::Commons::ConversionException);
218 const JSStringRef keyJSStr = JSStringCreateWithUTF8CString(key.c_str());
219 retVal = JSObjectGetProperty(m_context, argObj, keyJSStr, NULL);
220 JSStringRelease(keyJSStr);
221 if (NULL == retVal) {
222 LogWarning("key \"" << key << "\" not found in JSValue map");
224 // return NULL if no key in map
228 IMessagePtr ConverterMessage::toIMessage(JSValueRef arg)
230 return toIMessage(toJSObjectRef(arg));
233 IMessagePtr ConverterMessage::toIMessage(JSObjectRef arg)
235 LogDebug("message object=" << arg);
237 LogError("Object is null");
238 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
239 "Private object not initialized");
242 // get private object
243 JSMessagePrivateObject* priv =
244 static_cast<JSMessagePrivateObject*>(JSObjectGetPrivate(arg));
246 LogError("Private object not initialized");
247 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
248 "Private object not initialized");
250 retVal = priv->getObject();
252 LogError("Message private object not initialized");
253 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
254 "Private object not initialized");
259 IAttachmentPtr ConverterMessage::toIAttachment(JSValueRef arg)
261 return toIAttachment(toJSObjectRef(arg));
264 IAttachmentPtr ConverterMessage::toIAttachment(JSObjectRef arg)
268 LogError("Object is Null");
269 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
272 IAttachmentPtr retVal;
273 JSMessageAttachmentPrivate* priv =
274 static_cast<JSMessageAttachmentPrivate*>(JSObjectGetPrivate(arg));
277 LogError("Private object not initialized");
278 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
279 "Private object not initialized");
282 retVal = priv->getObject();
284 LogError("Message private object not initialized");
285 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
286 "Private object not initialized");
291 IMessageFolderPtr ConverterMessage::toIMessageFolder(JSValueRef arg)
293 return toIMessageFolder(toJSObjectRef(arg));
296 IMessageFolderPtr ConverterMessage::toIMessageFolder(JSObjectRef arg)
300 LogError("Object is Null");
301 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
304 IMessageFolderPtr retVal;
305 JSMessageFolderPriv* priv =
306 static_cast<JSMessageFolderPriv*>(JSObjectGetPrivate(arg));
309 LogError("Private object not initialized");
310 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
311 "Private object not initialized");
314 retVal = priv->getObject();
316 LogError("Message private object not initialized");
317 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
318 "Private object not initialized");
323 Recipients ConverterMessage::toRecipients(JSValueRef arg)
325 if (JSValueIsObjectOfClass(m_context, arg,
326 JSRecipientArray::getClassRef())) {
327 RecipientsPtr recipients =
328 JSRecipientArray::getRecipients(m_context, toJSObjectRef(arg));
330 Throw(WrtDeviceApis::Commons::ConversionException);
335 // convert JS value to vector of recipient addresses
336 vector<string> recip = toVectorOfStrings(arg);
337 retVal.setRecipients(recip);
341 OnMessagesChanged ConverterMessage::toMessageMultifunctions(JSValueRef argument)
343 OnMessagesChanged result;
344 Validator validator(m_context);
345 JSObjectRef objectCallbacks = toJSObjectRef(argument);
346 std::string callbackName = toString(argument);
351 for (index = 0; index < MESSAGING_MULTI_FUNTION_MAX; index++)
353 ScopedJSStringRef propName(toJSStringRef(m_callbackNames[index].addedFunction));
355 if (JSObjectHasProperty(m_context, objectCallbacks, propName.get()))
357 LogDebug("Callback name :" << m_callbackNames[index].addedFunction << " "
358 << m_callbackNames[index].updatedFunction << " " << m_callbackNames[index].removedFunction);
360 result.messagesAdded = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].addedFunction);
361 result.messagesUpdated = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].updatedFunction);
362 result.messagesRemoved = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].removedFunction);
368 if(result.messagesAdded == NULL || result.messagesUpdated == NULL || result.messagesRemoved == NULL)
370 LogError("OnMessagesChanged is not set");
371 Throw(WrtDeviceApis::Commons::ConversionException);
374 result.functionIndex = index;
376 if ((!validator.isNullOrUndefined(result.messagesAdded) && !validator.isCallback(result.messagesAdded)) ||
377 (!validator.isNullOrUndefined(result.messagesUpdated) && !validator.isCallback(result.messagesUpdated)) ||
378 (!validator.isNullOrUndefined(result.messagesRemoved) && !validator.isCallback(result.messagesRemoved)))
380 LogError("java script call back set error");
381 Throw(WrtDeviceApis::Commons::ConversionException);
388 std::vector<FolderType> ConverterMessage::toVectorOfFolderTypes(
391 return toVectorOfT_(arg, &ConverterMessage::toFolderType, this);
394 FolderType ConverterMessage::toFolderType(const JSValueRef& arg)
396 // convert JS value to folder type
397 messageFolders folder = static_cast<messageFolders>(toInt(arg));
399 case messageFolderInbox:
401 case messageFolderOutbox:
403 case messageFolderDrafts:
405 case messageFolderSentbox:
408 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "folder not supported");
412 MessageType ConverterMessage::toMessageType(JSValueRef arg)
414 return toMessageType(toJSObjectRef(arg));
417 MessageType ConverterMessage::toMessageType(JSObjectRef arg)
419 // convert JSvalue to message type enum
420 std::string strMsgType = toString(arg);
421 LogDebug("Messasge Type : " << strMsgType);
423 if ( strMsgType.compare("messaging.sms") == 0 )
427 else if ( strMsgType.compare("messaging.mms") == 0 )
431 else if ( strMsgType.compare("messaging.email") == 0 )
437 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
442 std::string ConverterMessage::toMessageType( long msgtype )
444 LogDebug("Messasge Type : " << msgtype);
449 return "messaging.sms";
451 return "messaging.mms";
453 return "messaging.email";
455 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
459 MessageType ConverterMessage::toMessageType(std::string arg)
461 LogDebug("Messasge Type : " << arg);
463 if ( arg.compare("messaging.sms") == 0 )
467 else if ( arg.compare("messaging.mms") == 0 )
471 else if ( arg.compare("messaging.email") == 0 )
477 std::string message = "Message type " + arg + " not supported.";
478 throw DeviceAPI::Common::TypeMismatchException(message.c_str());
483 std::string ConverterMessage::toMessageStatusType( long msgstatus )
485 LogDebug("Messasge Status : " << msgstatus);
489 case MESSAGE_STATUS_SENT:
491 case MESSAGE_STATUS_SENDING:
493 case MESSAGE_STATUS_FAILED:
495 case MESSAGE_STATUS_DRAFT:
497 case MESSAGE_STATUS_CREATED:
498 case MESSAGE_STATUS_LOADED:
501 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message status not supported");
505 std::string ConverterMessage::convertIntToString( int msgInt )
507 LogDebug("input int : " << msgInt);
508 std::stringstream stream;
513 IConversationPtr ConverterMessage::toConversation(const JSValueRef& arg)
515 return JSConversation::getConversation(m_context, arg);
518 std::vector<IConversationPtr> ConverterMessage::toVectorOfConversation(const JSValueRef& arg)
520 std::vector<IConversationPtr> result;
522 JSObjectRef jsObject = toJSObjectRef(arg);
524 if( JSGetArrayLength(m_context, jsObject) == 0)
526 LogError("this is empty conversation");
527 Throw(WrtDeviceApis::Commons::ConversionException);
530 for (std::size_t i = 0; i < JSGetArrayLength(m_context, jsObject); ++i)
532 JSValueRef element = JSGetArrayElement(m_context, jsObject, i);
533 result.push_back(toConversation(element));
539 AddressType ConverterMessage::toAddressType(JSValueRef arg)
541 // convert JSvalue to address type enum
542 string addressType = toString(arg);
543 if ("destination" == addressType) {
545 } else if ("cc" == addressType) {
547 } else if ("bcc" == addressType) {
550 LogError("unknown address type");
551 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
555 MessagePriority::Priority ConverterMessage::toMessagePriority(
559 return MessagePriority::HIGH;
561 return MessagePriority::NORMAL;
565 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
566 DeviceAPI::Filesystem::INodePtr ConverterMessage::toFilesystemNode(JSValueRef arg)
568 // TODO It doesn't work even when object IS a JS File, not sure what to do?
569 // if (!JSValueIsObjectOfClass(m_context, arg, JSFile::getClassRef())) {
570 // ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a JSFile object.");
573 JSObjectRef attObj = toJSObjectRef(arg);
574 JSFile::PrivateObject* privateObject =
575 static_cast<JSFile::PrivateObject*>(JSObjectGetPrivate(attObj));
576 if (!privateObject) {
577 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
580 DeviceAPI::Filesystem::INodePtr result = privateObject->getObject();
582 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Node object is NULL.");
589 JSValueRef ConverterMessage::toFunctionOrNull(const JSValueRef& arg)
591 Assert(arg && "Argument is NULL.");
593 if (Validator(m_context).isCallback(arg)) {
595 } else if (!JSValueIsNull(m_context, arg) ) {
596 ThrowMsg(ConversionException, "Not a function nor JS null.");
601 JSValueRef ConverterMessage::toFunction(const JSValueRef& arg)
603 Assert(arg && "Argument is NULL.");
605 if (Validator(m_context).isCallback(arg)) {
607 } else if (JSValueIsNull(m_context,
608 arg) || JSValueIsUndefined(m_context, arg)) {
609 ThrowMsg(InvalidArgumentException, "JS null passed as function.");
611 ThrowMsg(ConversionException, "Not a function nor JS null.");
615 ConverterMessage::toMessageSendCallback(const JSValueRef& arg)
617 JSObjectRef object = toJSObjectRef(arg);
619 MessageSendCallback result;
620 Validator validator(m_context);
622 result.onSuccess = JSUtils::getJSPropertyOrUndefined(
623 m_context, object, SEND_PROPERTY_ONSUCCESS
625 if (!validator.isNullOrUndefined(result.onSuccess) &&
626 !validator.isCallback(result.onSuccess)) {
627 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
630 result.onMessageSendSuccess = JSUtils::getJSPropertyOrUndefined(
631 m_context, object, SEND_PROPERTY_ONMESSAGESENDSUCCESS
633 if (!validator.isNullOrUndefined(result.onMessageSendSuccess) &&
634 !validator.isCallback(result.onMessageSendSuccess)) {
635 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
638 result.onMessageSendError = JSUtils::getJSPropertyOrUndefined(
639 m_context, object, SEND_PROPERTY_ONMESSAGESENDERROR
641 if (!validator.isNullOrUndefined(result.onMessageSendError) &&
642 !validator.isCallback(result.onMessageSendError)) {
643 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");