wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / Messaging / JSMessageBody.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 <iomanip>
19 #include <CommonsJavaScript/Converter.h>
20 #include <CommonsJavaScript/JSUtils.h>
21 #include "ConverterMessage.h"
22 #include "JSMessageBody.h"
23 #include <JSTizenExceptionFactory.h>
24 #include <JSTizenException.h>
25 #include "MessagingErrorMsg.h"
26 #include "JSMessageAttachment.h"
27 #include <JSWebAPIError.h>
28 #include <ArgumentValidator.h>
29 #include <JSUtil.h>
30 #include <Logger.h>
31
32 namespace DeviceAPI {
33 namespace Messaging {
34
35 using namespace DeviceAPI::Common;
36 using namespace DeviceAPI::Messaging;
37 using namespace WrtDeviceApis::Commons;
38 using namespace WrtDeviceApis::CommonsJavaScript;
39
40 const char* JSMessageBody::MSGID = "messageId";
41 const char* JSMessageBody::LOADED = "loaded";
42 const char* JSMessageBody::PLAINBODY = "plainBody";
43 const char* JSMessageBody::HTMLBODY = "htmlBody";
44 const char* JSMessageBody::INLINEATT = "inlineAttachments";
45
46 JSClassRef JSMessageBody::m_jsClassRef = NULL;
47
48 JSClassDefinition JSMessageBody::m_classInfo = {
49     0,
50     kJSClassAttributeNone,
51     "MessageBody",
52     0,
53     m_property,
54     NULL,
55     initialize,
56     finalize,
57     NULL, //hasProperty,
58     getProperty,
59     setProperty,
60     NULL, //deleteProperty,
61     getPropertyNames,
62     NULL, //callAsFunction,
63     NULL, //callAsConstructor,
64     NULL, //hasInstance,
65     NULL, //convertToType,
66 };
67
68 JSStaticValue JSMessageBody::m_property[] = {
69     { 0, 0, 0, 0 }
70 };
71
72 const JSClassDefinition* JSMessageBody::getClassInfo()
73 {
74     return &(m_classInfo);
75 }
76
77 JSClassRef JSMessageBody::getClassRef()
78 {
79     if (!m_jsClassRef) {
80         m_jsClassRef = JSClassCreate(&m_classInfo);
81     }
82     return m_jsClassRef;
83 }
84
85 void JSMessageBody::initialize(JSContextRef context,
86         JSObjectRef object)
87 {
88     LoggerD("enter");
89 }
90
91 void JSMessageBody::finalize(JSObjectRef object)
92 {
93     LoggerD("enter");
94     JSMessageBodyPrivate* priv = static_cast<JSMessageBodyPrivate*>(JSObjectGetPrivate(object));
95     JSObjectSetPrivate(object, NULL);
96     delete priv;
97 }
98
99 JSObjectRef JSMessageBody::createJS( JSContextRef context, const IMessagePtr &msg)
100 {
101     JSMessageBodyPrivate *priv = new JSMessageBodyPrivate(context, msg);
102     return JSObjectMake(context, getClassRef(), priv); //make JSObjectRef.
103 }
104
105 IMessagePtr JSMessageBody::getMessage(JSContextRef context,
106         JSValueRef value)
107 {
108     WrtDeviceApis::CommonsJavaScript::Converter converter(context);
109     return getMessage(context, converter.toJSObjectRef(value));
110 }
111
112 IMessagePtr JSMessageBody::getMessage(JSContextRef context,
113         JSObjectRef object)
114 {
115     return getPrivate(object)->getObject();
116 }
117
118 JSMessageBodyPrivate* JSMessageBody::getPrivate(JSObjectRef thisObject)
119 {
120     JSMessageBodyPrivate* thisPrivate = static_cast<JSMessageBodyPrivate*>(JSObjectGetPrivate(thisObject));
121     if (!thisPrivate) {
122         LoggerE("no private");
123         Throw(WrtDeviceApis::Commons::NullPointerException);
124     }
125     return thisPrivate;
126 }
127
128 JSValueRef JSMessageBody::getProperty(JSContextRef context,
129         JSObjectRef object,
130         JSStringRef propertyName,
131         JSValueRef* exception)
132 {
133     LoggerD("Entered");
134
135     try {
136        IMessagePtr msg = getMessage(context, object);
137         if (msg == NULL) {
138             throw DeviceAPI::Common::UnknownException("Object is null");
139         }
140
141         if (JSStringIsEqualToUTF8CString(propertyName, MSGID)) {
142             std::string id = msg->getId();
143             LoggerD("msgId=" << id);
144             LoggerD("msg->getMessageStatus()=" << msg->getMessageStatus());
145             if((id.size() == 0) && (msg->getMessageStatus() == MESSAGE_STATUS_CREATED)) {
146                 id = "";
147             }
148             return JSUtil::toJSValueRef(context, id);
149         }
150         else if (JSStringIsEqualToUTF8CString(propertyName, LOADED)) {
151             if (msg->getMessageType() == EMAIL) {
152                 IEmailPtr email = MessageFactory::convertToEmail(msg);
153                 return JSUtil::toJSValueRef(context, email->isBodyDownloaded() > 0 ? true : false);
154             }
155             else {
156                LoggerD("msgId=" << msg->getId());
157                LoggerD("msg->getMessageStatus()=" << msg->getMessageStatus());
158                 if ((msg->getId().size() == 0) && msg->getMessageStatus() == MESSAGE_STATUS_CREATED) {
159                     return JSUtil::toJSValueRef(context, false);
160                 }
161                 return JSUtil::toJSValueRef(context, true);
162             }
163         }
164         else if (JSStringIsEqualToUTF8CString(propertyName, PLAINBODY)) {
165            std::string body = msg->getBody();
166            LoggerD("getPlainBody plainBody" << body );
167            return JSUtil::toJSValueRef(context, body);
168         }
169         else if (JSStringIsEqualToUTF8CString(propertyName, HTMLBODY)) {
170            LoggerD("message Type : " << msg->getMessageType() );
171            std::string emailHtmlBody = "";
172            if (msg->getMessageType() == EMAIL) {
173                IEmailPtr email = MessageFactory::convertToEmail(msg);
174                emailHtmlBody = email->getHtmlBody();
175                LoggerD("Html Body : " << emailHtmlBody );
176            }
177            return JSUtil::toJSValueRef(context, emailHtmlBody);
178         }
179         else if (JSStringIsEqualToUTF8CString(propertyName, INLINEATT)) {
180             switch(msg->getMessageType()) {
181                 case EMAIL:
182                 {
183                     std::vector<IAttachmentPtr> inlineAttachments;
184                     std::vector<IAttachmentPtr>::iterator it;
185                     int count = 0;
186
187                     AttachmentsPtr emailAttachments =
188                     DPL::StaticPointerCast<Attachments>(MessageFactory::convertToEmail(msg));
189                     inlineAttachments = emailAttachments->getInlineAttachments();
190                     count = inlineAttachments.size();
191
192                     LoggerD( "attachments.size(): " << count);
193
194                     JSObjectRef jsMessageAttachmentObject[count]; //make
195                     for(int i = 0; i < count; i++) {
196                         LoggerD("Attachment ID: " << inlineAttachments[i]->getAttachmentID());
197                         jsMessageAttachmentObject[i] = JSMessageAttachment::createJS(context, inlineAttachments[i]);
198                     }
199                     JSObjectRef result = JSObjectMakeArray(context, count, jsMessageAttachmentObject, NULL);
200                     return result;
201                 }
202                 case SMS:
203                 case MMS:
204                 {
205                     JSObjectRef arrayValue = JSObjectMakeArray(context, 0, NULL, NULL);
206                     if(NULL == arrayValue){
207                         LoggerE("Could not create JS array object");
208                         return JSValueMakeUndefined(context);
209                     }
210                     return arrayValue;
211                 }
212
213                 default:
214                    throw DeviceAPI::Common::UnknownException("Not supported message type.");
215             }
216         }
217         else {
218             LoggerD("Not supported property.");
219         }
220     }
221     catch (const BasePlatformException& err) {
222         LoggerE(err.getMessage().c_str());
223         return JSValueMakeUndefined(context);
224     }
225     catch (const WrtDeviceApis::Commons::Exception& err) {
226         LoggerE(err.GetMessage().c_str());
227         return JSValueMakeUndefined(context);
228     }
229
230     return NULL;
231 }
232
233 bool JSMessageBody::setProperty(JSContextRef context,
234         JSObjectRef object,
235         JSStringRef propertyName,
236         JSValueRef value,
237         JSValueRef* exception)
238 {
239     LoggerD("Entered");
240
241     try {
242         if (JSStringIsEqualToUTF8CString(propertyName, MSGID)) {
243             return true;
244         }
245         else if (JSStringIsEqualToUTF8CString(propertyName, LOADED)) {
246             return true;
247         }
248         else if(JSStringIsEqualToUTF8CString(propertyName, PLAINBODY)) {
249             IMessagePtr msg = getMessage(context, object);
250             std::string body = JSUtil::JSValueToString(context, value);
251             msg->setBody(body);
252             LoggerD("setPlainBody plainBody" << body );
253             return true;
254         }
255         else if (JSStringIsEqualToUTF8CString(propertyName, HTMLBODY)) {
256             IMessagePtr msg = getMessage(context, object);
257
258             if (msg->getMessageType() == EMAIL)
259             {
260                 IEmailPtr email = MessageFactory::convertToEmail(msg);
261                 std::string body = JSUtil::JSValueToString(context, value);
262                 LoggerD("input String : " << body);
263                 email->setHtmlBody(body);
264                 return true;
265             }
266             else {
267                 throw DeviceAPI::Common::NotSupportedException("HTML body is for Email only.");
268             }
269             return true;
270         }
271         else if (JSStringIsEqualToUTF8CString(propertyName, INLINEATT)) {
272             ConverterMessageFactory::ConverterType converter = ConverterMessageFactory::getConverter(context);
273
274             std::vector<IAttachmentPtr> inlineAttachments;
275             if (JSIsArrayValue(context, value)) {
276                 JSObjectRef valueObj = converter->toJSObjectRef(value);
277                 unsigned int len = JSGetArrayLength(context, valueObj);
278                 LoggerD("Array Length = " << len);
279                 for (unsigned int i = 0; i < len; ++i) {
280
281                     JSValueRef att = JSGetArrayElement(context, valueObj, i);
282                     if (JSValueIsUndefined(context, att) || JSValueIsNull(context, att)) {
283                         LoggerW("Invalid array element. Skipping.");
284                         continue;
285                     }
286                     IAttachmentPtr attachment = converter->toIAttachment(att);
287
288                     if (attachment->getIsValidAttachment() == false) {
289                         std::string logMsg = "Invalid attachment : " + i;
290                         throw DeviceAPI::Common::InvalidValuesException(logMsg.c_str());
291                     }
292
293                     LoggerD("Adding attachment , shortname: " << attachment->getShortName());
294                     inlineAttachments.push_back(attachment);
295                 }
296             }
297             else {
298                 IAttachmentPtr attachment = converter->toIAttachment(value);
299                 LoggerD("Adding attachment , shortname: " << attachment->getShortName());
300                 if (attachment->getIsValidAttachment() == false) {
301                     throw DeviceAPI::Common::InvalidValuesException("Invalid attachment.");
302                 }
303                 inlineAttachments.push_back(attachment);
304             }
305
306             LoggerD("inlineAttachments Size =" << inlineAttachments.size());
307             if ( inlineAttachments.size() > 0) {
308                 IMessagePtr msg = converter->toIMessage(object);
309                 if (msg) {
310                     MessageType msgType = msg->getMessageType();
311                     switch (msgType) {
312                         case EMAIL:
313                         {
314                             IEmailPtr email = MessageFactory::convertToEmail(msg);
315                             email->setInlineAttachments(inlineAttachments);
316                             break;
317                         }
318                         default:
319                             throw DeviceAPI::Common::NotSupportedException("Not supported message type.");
320                     }
321                 }
322                 else {
323                     throw DeviceAPI::Common::UnknownException("Message converter failed.");
324                 }
325             }
326             return true;
327         }
328         else {
329             LoggerD("Not supported property.");
330         }
331     }
332     catch (const BasePlatformException& err) {
333         LoggerE(err.getMessage().c_str());
334         return true;
335     }
336     catch (const WrtDeviceApis::Commons::Exception& err) {
337         LoggerE(err.GetMessage().c_str());
338         return true;
339     }
340
341     return false;
342 }
343
344 void JSMessageBody::getPropertyNames(JSContextRef context,
345         JSObjectRef object,
346         JSPropertyNameAccumulatorRef propertyNames)
347 {
348     LoggerD("Entered");
349     JSStringRef propertyName = NULL;
350
351     propertyName = JSStringCreateWithUTF8CString(MSGID);
352     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
353     JSStringRelease(propertyName);
354
355     propertyName = JSStringCreateWithUTF8CString(LOADED);
356     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
357     JSStringRelease(propertyName);
358
359     propertyName = JSStringCreateWithUTF8CString(PLAINBODY);
360     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
361     JSStringRelease(propertyName);
362
363     propertyName = JSStringCreateWithUTF8CString(HTMLBODY);
364     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
365     JSStringRelease(propertyName);
366
367     propertyName = JSStringCreateWithUTF8CString(INLINEATT);
368     JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
369     JSStringRelease(propertyName);
370 }
371
372 }
373 }
374