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 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
39 using namespace WrtDeviceApis::Commons;
40 using namespace WrtDeviceApis::CommonsJavaScript;
43 const char* SEND_PROPERTY_ONSUCCESS = "onsuccess";
44 const char* SEND_PROPERTY_ONMESSAGESENDSUCCESS = "onmessagesendsuccess";
45 const char* SEND_PROPERTY_ONMESSAGESENDERROR = "onmessagesenderror";
51 MessageFunctions ConverterMessage::m_callbackNames[MESSAGING_MULTI_FUNTION_MAX]
53 {"messagesadded", "messagesupdated", "messagesremoved"},
54 {"conversationsadded", "conversationsupdated", "conversationsremoved"},
55 {"foldersadded", "foldersupdated", "foldersremoved"}
58 ConverterMessage::ConverterMessage(JSContextRef context) :
63 ConverterMessage::~ConverterMessage()
67 JSContextRef ConverterMessage::toJSGlobalContext(JSObjectRef arg)
70 WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type* priv =
71 static_cast<WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type*>(JSObjectGetPrivate(
74 LogError("Private object not initialized");
75 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
76 "Private object not initialized");
78 return priv->getContext();
81 JSValueRef ConverterMessage::toJSValueRef(FolderType arg)
85 return toJSValueRef(messageFolderInbox);
87 return toJSValueRef(messageFolderOutbox);
89 return toJSValueRef(messageFolderDrafts);
91 return toJSValueRef(messageFolderSentbox);
93 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "folder not supported");
97 JSValueRef ConverterMessage::toJSValueRef(MessageType arg)
101 return toJSValueRef(messageTypeSms);
103 return toJSValueRef(messageTypeMms);
105 return toJSValueRef(messageTypeEmail);
107 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
111 JSValueRef ConverterMessage::toJSValueRef(const IMessagePtr& arg)
113 switch (arg->getMessageType()) {
118 return JSMessage::createJSObject(m_context, arg);
121 LogError("unknown type");
122 Throw(WrtDeviceApis::Commons::ConversionException);
126 JSValueRef ConverterMessage::toJSValueRef(const IMessagePtr& arg,
127 EventUpdateMessageAnswerReceiver* listener)
129 switch (arg->getMessageType()) {
134 return JSMessage::createJSObject(m_context, arg, listener);
137 LogError("unknown type");
138 Throw(WrtDeviceApis::Commons::ConversionException);
142 JSValueRef ConverterMessage::toJSValueRef(
143 const std::vector<IMessagePtr>& arg,
144 EventUpdateMessageAnswerReceiver* listener)
146 vector<JSValueRef> msgsJS;
147 for (size_t i = 0; i < arg.size(); i++) {
148 msgsJS.push_back(toJSValueRef(arg[i], listener));
150 return toJSValueRef(msgsJS);
153 JSValueRef ConverterMessage::toJSValueRef(const std::vector<IConversationPtr>& conversations)
155 vector<JSValueRef> conversationJS;
157 for (size_t i = 0; i < conversations.size(); i++)
159 JSValueRef value = JSConversation::createJSObject(m_context, conversations[i]);
160 conversationJS.push_back(value);
163 return toJSValueRef(conversationJS);
166 JSValueRef ConverterMessage::toJSValueRef(const std::vector<IMessageFolderPtr>& messagefolders)
168 vector<JSValueRef> messagefolderJS;
170 for (size_t i = 0; i < messagefolders.size(); i++)
172 JSValueRef value = JSMessageFolder::createJSObject(m_context, messagefolders[i]);
173 messagefolderJS.push_back(value);
176 return toJSValueRef(messagefolderJS);
179 JSValueRef ConverterMessage::toJSValueRef(const MessagePriority& arg)
181 switch (arg.getPriority()) {
182 case MessagePriority::LOW:
183 return toJSValueRef(false);
185 case MessagePriority::NORMAL:
186 return toJSValueRef(false);
188 case MessagePriority::HIGH:
189 return toJSValueRef(true);
192 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Unknown priority");
197 JSValueRef ConverterMessage::toJSValueRef(const IAttachmentPtr& arg)
199 return JSMessageAttachment::createJS(m_context, arg);
202 JSValueRef ConverterMessage::keyToJSValue(JSValueRef value,
205 JSValueRef retVal = NULL;
208 LogError("jsValue null");
209 Throw(WrtDeviceApis::Commons::ConversionException);
211 JSObjectRef argObj = JSValueToObject(m_context, value, NULL);
212 if (NULL == argObj) {
213 LogError("conversion to jsobject fail");
214 Throw(WrtDeviceApis::Commons::ConversionException);
216 const JSStringRef keyJSStr = JSStringCreateWithUTF8CString(key.c_str());
217 retVal = JSObjectGetProperty(m_context, argObj, keyJSStr, NULL);
218 JSStringRelease(keyJSStr);
219 if (NULL == retVal) {
220 LogWarning("key \"" << key << "\" not found in JSValue map");
222 // return NULL if no key in map
226 IMessagePtr ConverterMessage::toIMessage(JSValueRef arg)
228 return toIMessage(toJSObjectRef(arg));
231 IMessagePtr ConverterMessage::toIMessage(JSObjectRef arg)
233 LogDebug("message object=" << arg);
235 LogError("Object is null");
236 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
237 "Private object not initialized");
240 // get private object
241 JSMessagePrivateObject* priv =
242 static_cast<JSMessagePrivateObject*>(JSObjectGetPrivate(arg));
244 LogError("Private object not initialized");
245 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
246 "Private object not initialized");
248 retVal = priv->getObject();
250 LogError("Message private object not initialized");
251 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
252 "Private object not initialized");
257 IAttachmentPtr ConverterMessage::toIAttachment(JSValueRef arg)
259 return toIAttachment(toJSObjectRef(arg));
262 IAttachmentPtr ConverterMessage::toIAttachment(JSObjectRef arg)
266 LogError("Object is Null");
267 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
270 IAttachmentPtr retVal;
271 JSMessageAttachmentPrivate* priv =
272 static_cast<JSMessageAttachmentPrivate*>(JSObjectGetPrivate(arg));
275 LogError("Private object not initialized");
276 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
277 "Private object not initialized");
280 retVal = priv->getObject();
282 LogError("Message private object not initialized");
283 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
284 "Private object not initialized");
289 IMessageFolderPtr ConverterMessage::toIMessageFolder(JSValueRef arg)
291 return toIMessageFolder(toJSObjectRef(arg));
294 IMessageFolderPtr ConverterMessage::toIMessageFolder(JSObjectRef arg)
298 LogError("Object is Null");
299 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
302 IMessageFolderPtr retVal;
303 JSMessageFolderPriv* priv =
304 static_cast<JSMessageFolderPriv*>(JSObjectGetPrivate(arg));
307 LogError("Private object not initialized");
308 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
309 "Private object not initialized");
312 retVal = priv->getObject();
314 LogError("Message private object not initialized");
315 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
316 "Private object not initialized");
321 Recipients ConverterMessage::toRecipients(JSValueRef arg)
323 if (JSValueIsObjectOfClass(m_context, arg,
324 JSRecipientArray::getClassRef())) {
325 RecipientsPtr recipients =
326 JSRecipientArray::getRecipients(m_context, toJSObjectRef(arg));
328 Throw(WrtDeviceApis::Commons::ConversionException);
333 // convert JS value to vector of recipient addresses
334 vector<string> recip = toVectorOfStrings(arg);
335 retVal.setRecipients(recip);
339 OnMessagesChanged ConverterMessage::toMessageMultifunctions(JSValueRef argument)
341 OnMessagesChanged result;
342 Validator validator(m_context);
343 JSObjectRef objectCallbacks = toJSObjectRef(argument);
344 std::string callbackName = toString(argument);
349 for (index = 0; index < MESSAGING_MULTI_FUNTION_MAX; index++)
351 ScopedJSStringRef propName(toJSStringRef(m_callbackNames[index].addedFunction));
353 if (JSObjectHasProperty(m_context, objectCallbacks, propName.get()))
355 LogDebug("Callback name :" << m_callbackNames[index].addedFunction << " "
356 << m_callbackNames[index].updatedFunction << " " << m_callbackNames[index].removedFunction);
358 result.messagesAdded = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].addedFunction);
359 result.messagesUpdated = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].updatedFunction);
360 result.messagesRemoved = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[index].removedFunction);
366 if(result.messagesAdded == NULL || result.messagesUpdated == NULL || result.messagesRemoved == NULL)
368 LogError("OnMessagesChanged is not set");
369 Throw(WrtDeviceApis::Commons::ConversionException);
372 result.functionIndex = index;
374 if ((!validator.isNullOrUndefined(result.messagesAdded) && !validator.isCallback(result.messagesAdded)) ||
375 (!validator.isNullOrUndefined(result.messagesUpdated) && !validator.isCallback(result.messagesUpdated)) ||
376 (!validator.isNullOrUndefined(result.messagesRemoved) && !validator.isCallback(result.messagesRemoved)))
378 LogError("java script call back set error");
379 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
386 std::vector<FolderType> ConverterMessage::toVectorOfFolderTypes(
389 return toVectorOfT_(arg, &ConverterMessage::toFolderType, this);
392 FolderType ConverterMessage::toFolderType(const JSValueRef& arg)
394 // convert JS value to folder type
395 messageFolders folder = static_cast<messageFolders>(toInt(arg));
397 case messageFolderInbox:
399 case messageFolderOutbox:
401 case messageFolderDrafts:
403 case messageFolderSentbox:
406 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "folder not supported");
410 MessageType ConverterMessage::toMessageType(JSValueRef arg)
412 return toMessageType(toJSObjectRef(arg));
415 MessageType ConverterMessage::toMessageType(JSObjectRef arg)
417 // convert JSvalue to message type enum
418 std::string strMsgType = toString(arg);
419 LogDebug("Messasge Type : " << strMsgType);
421 if ( strMsgType.compare("messaging.sms") == 0 )
425 else if ( strMsgType.compare("messaging.mms") == 0 )
429 else if ( strMsgType.compare("messaging.email") == 0 )
435 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
440 std::string ConverterMessage::toMessageType( long msgtype )
442 LogDebug("Messasge Type : " << msgtype);
447 return "messaging.sms";
449 return "messaging.mms";
451 return "messaging.email";
453 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
457 std::string ConverterMessage::toMessageStatusType( long msgstatus )
459 LogDebug("Messasge Status : " << msgstatus);
463 case MESSAGE_STATUS_SENT:
465 case MESSAGE_STATUS_SENDING:
467 case MESSAGE_STATUS_FAILED:
469 case MESSAGE_STATUS_DRAFT:
471 case MESSAGE_STATUS_CREATED:
472 case MESSAGE_STATUS_LOADED:
475 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message status not supported");
479 std::string ConverterMessage::convertIntToString( int msgInt )
481 LogDebug("input int : " << msgInt);
482 std::stringstream stream;
487 IConversationPtr ConverterMessage::toConversation(const JSValueRef& arg)
489 return JSConversation::getConversation(m_context, arg);
492 std::vector<IConversationPtr> ConverterMessage::toVectorOfConversation(const JSValueRef& arg)
494 std::vector<IConversationPtr> result;
496 JSObjectRef jsObject = toJSObjectRef(arg);
498 if( JSGetArrayLength(m_context, jsObject) == 0)
500 LogError("this is empty conversation");
501 Throw(WrtDeviceApis::Commons::ConversionException);
504 for (std::size_t i = 0; i < JSGetArrayLength(m_context, jsObject); ++i)
506 JSValueRef element = JSGetArrayElement(m_context, jsObject, i);
507 result.push_back(toConversation(element));
513 AddressType ConverterMessage::toAddressType(JSValueRef arg)
515 // convert JSvalue to address type enum
516 string addressType = toString(arg);
517 if ("destination" == addressType) {
519 } else if ("cc" == addressType) {
521 } else if ("bcc" == addressType) {
524 LogError("unknown address type");
525 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
529 MessagePriority::Priority ConverterMessage::toMessagePriority(
533 return MessagePriority::HIGH;
535 return MessagePriority::NORMAL;
539 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
540 DeviceAPI::Filesystem::INodePtr ConverterMessage::toFilesystemNode(JSValueRef arg)
542 // TODO It doesn't work even when object IS a JS File, not sure what to do?
543 // if (!JSValueIsObjectOfClass(m_context, arg, JSFile::getClassRef())) {
544 // ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a JSFile object.");
547 JSObjectRef attObj = toJSObjectRef(arg);
548 JSFile::PrivateObject* privateObject =
549 static_cast<JSFile::PrivateObject*>(JSObjectGetPrivate(attObj));
550 if (!privateObject) {
551 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
554 DeviceAPI::Filesystem::INodePtr result = privateObject->getObject();
556 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Node object is NULL.");
563 JSValueRef ConverterMessage::toFunctionOrNull(const JSValueRef& arg)
565 Assert(arg && "Argument is NULL.");
567 if (Validator(m_context).isCallback(arg)) {
569 } else if (!JSValueIsNull(m_context, arg) ) {
570 ThrowMsg(ConversionException, "Not a function nor JS null.");
575 JSValueRef ConverterMessage::toFunction(const JSValueRef& arg)
577 Assert(arg && "Argument is NULL.");
579 if (Validator(m_context).isCallback(arg)) {
581 } else if (JSValueIsNull(m_context,
582 arg) || JSValueIsUndefined(m_context, arg)) {
583 ThrowMsg(InvalidArgumentException, "JS null passed as function.");
585 ThrowMsg(ConversionException, "Not a function nor JS null.");
589 ConverterMessage::toMessageSendCallback(const JSValueRef& arg)
591 JSObjectRef object = toJSObjectRef(arg);
593 MessageSendCallback result;
594 Validator validator(m_context);
596 result.onSuccess = JSUtils::getJSPropertyOrUndefined(
597 m_context, object, SEND_PROPERTY_ONSUCCESS
599 if (!validator.isNullOrUndefined(result.onSuccess) &&
600 !validator.isCallback(result.onSuccess)) {
601 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
604 result.onMessageSendSuccess = JSUtils::getJSPropertyOrUndefined(
605 m_context, object, SEND_PROPERTY_ONMESSAGESENDSUCCESS
607 if (!validator.isNullOrUndefined(result.onMessageSendSuccess) &&
608 !validator.isCallback(result.onMessageSendSuccess)) {
609 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
612 result.onMessageSendError = JSUtils::getJSPropertyOrUndefined(
613 m_context, object, SEND_PROPERTY_ONMESSAGESENDERROR
615 if (!validator.isNullOrUndefined(result.onMessageSendError) &&
616 !validator.isCallback(result.onMessageSendError)) {
617 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");