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>
37 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
42 using namespace WrtDeviceApis::Commons;
43 using namespace WrtDeviceApis::CommonsJavaScript;
46 const char* SEND_PROPERTY_ONSUCCESS = "onsuccess";
47 const char* SEND_PROPERTY_ONMESSAGESENDSUCCESS = "onmessagesendsuccess";
48 const char* SEND_PROPERTY_ONMESSAGESENDERROR = "onmessagesenderror";
54 MessageFunctions ConverterMessage::m_callbackNames[MESSAGING_MULTI_FUNTION_MAX]
56 {"messagesadded", "messagesupdated", "messagesremoved"},
57 {"conversationsadded", "conversationsupdated", "conversationsremoved"},
58 {"foldersadded", "foldersupdated", "foldersremoved"}
61 ConverterMessage::ConverterMessage(JSContextRef context) :
66 ConverterMessage::~ConverterMessage()
70 JSContextRef ConverterMessage::toJSGlobalContext(JSObjectRef arg)
73 WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type* priv =
74 static_cast<WrtDeviceApis::CommonsJavaScript::PrivateObjectT<void>::Type*>(JSObjectGetPrivate(
77 LoggerE("Private object not initialized");
78 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
79 "Private object not initialized");
81 return priv->getContext();
84 JSValueRef ConverterMessage::toJSValueRef(FolderType arg)
88 return toJSValueRef(messageFolderInbox);
90 return toJSValueRef(messageFolderOutbox);
92 return toJSValueRef(messageFolderDrafts);
94 return toJSValueRef(messageFolderSentbox);
96 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "folder not supported");
100 JSValueRef ConverterMessage::toJSValueRef(MessageType arg)
104 return toJSValueRef(messageTypeSms);
106 return toJSValueRef(messageTypeMms);
108 return toJSValueRef(messageTypeEmail);
110 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
114 JSValueRef ConverterMessage::toJSValueRef(const IMessagePtr& arg)
116 switch (arg->getMessageType()) {
121 return JSMessage::createJSObject(m_context, arg);
124 LoggerE("unknown type");
125 Throw(WrtDeviceApis::Commons::ConversionException);
129 JSValueRef ConverterMessage::toJSValueRef(const IMessagePtr& arg,
130 EventUpdateMessageAnswerReceiver* listener)
132 switch (arg->getMessageType()) {
137 return JSMessage::createJSObject(m_context, arg, listener);
140 LoggerE("unknown type");
141 Throw(WrtDeviceApis::Commons::ConversionException);
145 JSValueRef ConverterMessage::toJSValueRef(
146 const std::vector<IMessagePtr>& arg,
147 EventUpdateMessageAnswerReceiver* listener)
149 vector<JSValueRef> msgsJS;
150 for (size_t i = 0; i < arg.size(); i++) {
151 msgsJS.push_back(toJSValueRef(arg[i], listener));
153 return toJSValueRef(msgsJS);
156 JSValueRef ConverterMessage::toJSValueRef(const std::vector<IConversationPtr>& conversations)
158 vector<JSValueRef> conversationJS;
160 for (size_t i = 0; i < conversations.size(); i++)
162 JSValueRef value = JSConversation::createJSObject(m_context, conversations[i]);
163 conversationJS.push_back(value);
166 return toJSValueRef(conversationJS);
169 JSValueRef ConverterMessage::toJSValueRef(const std::vector<IMessageFolderPtr>& messagefolders)
171 vector<JSValueRef> messagefolderJS;
173 for (size_t i = 0; i < messagefolders.size(); i++)
175 JSValueRef value = JSMessageFolder::createJSObject(m_context, messagefolders[i]);
176 messagefolderJS.push_back(value);
179 return toJSValueRef(messagefolderJS);
182 JSValueRef ConverterMessage::toJSValueRef(const MessagePriority& arg)
184 switch (arg.getPriority()) {
185 case MessagePriority::LOW:
186 return toJSValueRef(false);
188 case MessagePriority::NORMAL:
189 return toJSValueRef(false);
191 case MessagePriority::HIGH:
192 return toJSValueRef(true);
195 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Unknown priority");
200 JSValueRef ConverterMessage::toJSValueRef(const IAttachmentPtr& arg)
202 return JSMessageAttachment::createJS(m_context, arg);
205 JSValueRef ConverterMessage::keyToJSValue(JSValueRef value,
208 JSValueRef retVal = NULL;
211 LoggerE("jsValue null");
212 Throw(WrtDeviceApis::Commons::ConversionException);
214 JSObjectRef argObj = JSValueToObject(m_context, value, NULL);
215 if (NULL == argObj) {
216 LoggerE("conversion to jsobject fail");
217 Throw(WrtDeviceApis::Commons::ConversionException);
219 const JSStringRef keyJSStr = JSStringCreateWithUTF8CString(key.c_str());
220 retVal = JSObjectGetProperty(m_context, argObj, keyJSStr, NULL);
221 JSStringRelease(keyJSStr);
222 if (NULL == retVal) {
223 LoggerW("key \"" << key << "\" not found in JSValue map");
225 // return NULL if no key in map
229 IMessagePtr ConverterMessage::toIMessage(JSValueRef arg)
231 return toIMessage(toJSObjectRef(arg));
234 IMessagePtr ConverterMessage::toIMessage(JSObjectRef arg)
236 LoggerD("message object=" << arg);
238 LoggerE("Object is null");
239 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
240 "Private object not initialized");
243 // get private object
244 JSMessagePrivateObject* priv =
245 static_cast<JSMessagePrivateObject*>(JSObjectGetPrivate(arg));
247 LoggerE("Private object not initialized");
248 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
249 "Private object not initialized");
251 retVal = priv->getObject();
253 LoggerE("Message private object not initialized");
254 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
255 "Private object not initialized");
260 IAttachmentPtr ConverterMessage::toIAttachment(JSValueRef arg)
262 return toIAttachment(toJSObjectRef(arg));
265 IAttachmentPtr ConverterMessage::toIAttachment(JSObjectRef arg)
269 LoggerE("Object is Null");
270 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
273 IAttachmentPtr retVal;
274 JSMessageAttachmentPrivate* priv =
275 static_cast<JSMessageAttachmentPrivate*>(JSObjectGetPrivate(arg));
278 LoggerE("Private object not initialized");
279 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
280 "Private object not initialized");
283 retVal = priv->getObject();
285 LoggerE("Message private object not initialized");
286 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
287 "Private object not initialized");
292 IMessageFolderPtr ConverterMessage::toIMessageFolder(JSValueRef arg)
294 return toIMessageFolder(toJSObjectRef(arg));
297 IMessageFolderPtr ConverterMessage::toIMessageFolder(JSObjectRef arg)
301 LoggerE("Object is Null");
302 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object not initialized");
305 IMessageFolderPtr retVal;
306 JSMessageFolderPriv* priv =
307 static_cast<JSMessageFolderPriv*>(JSObjectGetPrivate(arg));
310 LoggerE("Private object not initialized");
311 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
312 "Private object not initialized");
315 retVal = priv->getObject();
317 LoggerE("Message private object not initialized");
318 ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
319 "Private object not initialized");
324 Recipients ConverterMessage::toRecipients(JSValueRef arg)
326 if (JSValueIsObjectOfClass(m_context, arg,
327 JSRecipientArray::getClassRef())) {
328 RecipientsPtr recipients =
329 JSRecipientArray::getRecipients(m_context, toJSObjectRef(arg));
331 Throw(WrtDeviceApis::Commons::ConversionException);
336 // convert JS value to vector of recipient addresses
337 vector<string> recip = toVectorOfStrings(arg);
338 retVal.setRecipients(recip);
342 OnMessagesChanged ConverterMessage::toMessageMultifunctions(JSValueRef argument, int multiFuntionType)
346 LoggerD("multiFuntionType : " << multiFuntionType);
348 OnMessagesChanged result;
349 Validator validator(m_context);
350 JSObjectRef objectCallbacks = toJSObjectRef(argument);
352 ScopedJSStringRef propNameAdded(toJSStringRef(m_callbackNames[multiFuntionType].addedFunction));
353 ScopedJSStringRef propNameUpdated(toJSStringRef(m_callbackNames[multiFuntionType].updatedFunction));
354 ScopedJSStringRef propNameRemoved(toJSStringRef(m_callbackNames[multiFuntionType].removedFunction));
356 if(JSObjectHasProperty(m_context, objectCallbacks, propNameAdded.get()))
358 LoggerD("added exist");
359 result.messagesAdded = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[multiFuntionType].addedFunction);
360 if (validator.isNullOrUndefined(result.messagesAdded))
361 result.messagesAdded = NULL;
362 else if (!validator.isCallback(result.messagesAdded)) {
363 LoggerD("is not Callback");
364 ThrowMsg(ConversionException, "1nd argument's onsuccess attribute is not a 'function'");
367 if(JSObjectHasProperty(m_context, objectCallbacks, propNameUpdated.get()))
369 LoggerD("updated exist");
370 result.messagesUpdated = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[multiFuntionType].updatedFunction);
371 if (validator.isNullOrUndefined(result.messagesUpdated))
372 result.messagesUpdated = NULL;
373 else if (!validator.isCallback(result.messagesUpdated)) {
374 LoggerD("is not Callback");
375 ThrowMsg(ConversionException, "2nd argument's onsuccess attribute is not a 'function'");
378 if(JSObjectHasProperty(m_context, objectCallbacks, propNameRemoved.get()))
380 LoggerD("removed exist");
381 result.messagesRemoved = JSUtils::getJSPropertyOrUndefined(m_context, objectCallbacks, m_callbackNames[multiFuntionType].removedFunction);
382 if (validator.isNullOrUndefined(result.messagesRemoved))
383 result.messagesRemoved = NULL;
384 else if (!validator.isCallback(result.messagesRemoved)) {
385 LoggerD("is not Callback");
386 ThrowMsg(ConversionException, "3nd argument's onsuccess attribute is not a 'function'");
390 if(result.messagesAdded != NULL || result.messagesUpdated != NULL || result.messagesRemoved != NULL)
392 result.functionIndex = multiFuntionType;
399 std::vector<FolderType> ConverterMessage::toVectorOfFolderTypes(
402 return toVectorOfT_(arg, &ConverterMessage::toFolderType, this);
405 FolderType ConverterMessage::toFolderType(const JSValueRef& arg)
407 // convert JS value to folder type
408 messageFolders folder = static_cast<messageFolders>(toInt(arg));
410 case messageFolderInbox:
412 case messageFolderOutbox:
414 case messageFolderDrafts:
416 case messageFolderSentbox:
419 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "folder not supported");
423 MessageType ConverterMessage::toMessageType(JSValueRef arg)
425 return toMessageType(toJSObjectRef(arg));
428 MessageType ConverterMessage::toMessageType(JSObjectRef arg)
430 // convert JSvalue to message type enum
431 std::string strMsgType = toString(arg);
432 LoggerD("Messasge Type : " << strMsgType);
434 if ( strMsgType.compare("messaging.sms") == 0 )
438 else if ( strMsgType.compare("messaging.mms") == 0 )
442 else if ( strMsgType.compare("messaging.email") == 0 )
448 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
453 std::string ConverterMessage::toMessageType( long msgtype )
455 LoggerD("Messasge Type : " << msgtype);
460 return "messaging.sms";
462 return "messaging.mms";
464 return "messaging.email";
466 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message type not supported");
470 MessageType ConverterMessage::toMessageType(std::string arg)
472 LoggerD("Messasge Type : " << arg);
474 if ( arg.compare("messaging.sms") == 0 )
478 else if ( arg.compare("messaging.mms") == 0 )
482 else if ( arg.compare("messaging.email") == 0 )
488 std::string message = "Message type " + arg + " not supported.";
489 throw DeviceAPI::Common::TypeMismatchException(message.c_str());
494 std::string ConverterMessage::toMessageStatusType( long msgstatus )
496 LoggerD("Messasge Status : " << msgstatus);
500 case MESSAGE_STATUS_SENT:
502 case MESSAGE_STATUS_SENDING:
504 case MESSAGE_STATUS_FAILED:
506 case MESSAGE_STATUS_DRAFT:
508 case MESSAGE_STATUS_CREATED:
509 case MESSAGE_STATUS_LOADED:
512 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "message status not supported");
516 std::string ConverterMessage::convertIntToString( int msgInt )
518 LoggerD("input int : " << msgInt);
519 std::stringstream stream;
524 IConversationPtr ConverterMessage::toConversation(const JSValueRef& arg)
526 return JSConversation::getConversation(m_context, arg);
529 std::vector<IConversationPtr> ConverterMessage::toVectorOfConversation(const JSValueRef& arg)
531 std::vector<IConversationPtr> result;
533 JSObjectRef jsObject = toJSObjectRef(arg);
535 if( JSGetArrayLength(m_context, jsObject) == 0)
537 LoggerE("this is empty conversation");
538 Throw(WrtDeviceApis::Commons::ConversionException);
541 for (std::size_t i = 0; i < JSGetArrayLength(m_context, jsObject); ++i)
543 JSValueRef element = JSGetArrayElement(m_context, jsObject, i);
544 result.push_back(toConversation(element));
550 AddressType ConverterMessage::toAddressType(JSValueRef arg)
552 // convert JSvalue to address type enum
553 string addressType = toString(arg);
554 if ("destination" == addressType) {
556 } else if ("cc" == addressType) {
558 } else if ("bcc" == addressType) {
561 LoggerE("unknown address type");
562 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
566 MessagePriority::Priority ConverterMessage::toMessagePriority(
570 return MessagePriority::HIGH;
572 return MessagePriority::NORMAL;
576 #if 0 // MESSAGING ATTACHMENT IS BLOCKED
577 DeviceAPI::Filesystem::INodePtr ConverterMessage::toFilesystemNode(JSValueRef arg)
579 // TODO It doesn't work even when object IS a JS File, not sure what to do?
580 // if (!JSValueIsObjectOfClass(m_context, arg, JSFile::getClassRef())) {
581 // ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a JSFile object.");
584 JSObjectRef attObj = toJSObjectRef(arg);
585 JSFile::PrivateObject* privateObject =
586 static_cast<JSFile::PrivateObject*>(JSObjectGetPrivate(attObj));
587 if (!privateObject) {
588 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
591 DeviceAPI::Filesystem::INodePtr result = privateObject->getObject();
593 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Node object is NULL.");
600 JSValueRef ConverterMessage::toFunctionOrNull(const JSValueRef& arg)
602 Assert(arg && "Argument is NULL.");
604 if (Validator(m_context).isCallback(arg)) {
606 } else if (!JSValueIsNull(m_context, arg) ) {
607 ThrowMsg(ConversionException, "Not a function nor JS null.");
612 JSValueRef ConverterMessage::toFunction(const JSValueRef& arg)
614 Assert(arg && "Argument is NULL.");
616 if (Validator(m_context).isCallback(arg)) {
618 } else if (JSValueIsNull(m_context,
619 arg) || JSValueIsUndefined(m_context, arg)) {
620 ThrowMsg(InvalidArgumentException, "JS null passed as function.");
622 ThrowMsg(ConversionException, "Not a function nor JS null.");
626 ConverterMessage::toMessageSendCallback(const JSValueRef& arg)
628 JSObjectRef object = toJSObjectRef(arg);
630 MessageSendCallback result;
631 Validator validator(m_context);
633 result.onSuccess = JSUtils::getJSPropertyOrUndefined(
634 m_context, object, SEND_PROPERTY_ONSUCCESS
636 if (!validator.isNullOrUndefined(result.onSuccess) &&
637 !validator.isCallback(result.onSuccess)) {
638 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
641 result.onMessageSendSuccess = JSUtils::getJSPropertyOrUndefined(
642 m_context, object, SEND_PROPERTY_ONMESSAGESENDSUCCESS
644 if (!validator.isNullOrUndefined(result.onMessageSendSuccess) &&
645 !validator.isCallback(result.onMessageSendSuccess)) {
646 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");
649 result.onMessageSendError = JSUtils::getJSPropertyOrUndefined(
650 m_context, object, SEND_PROPERTY_ONMESSAGESENDERROR
652 if (!validator.isNullOrUndefined(result.onMessageSendError) &&
653 !validator.isCallback(result.onMessageSendError)) {
654 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Not a valid callback.");