wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / NFC / JSNdefMessage.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 "JSNdefMessage.h"
19 #include "JSNdefRecord.h"
20 #include "JSNdefRecordText.h"
21 #include "JSNdefRecordURI.h"
22 #include "JSNdefRecordMedia.h"
23 #include "NFCConverter.h"
24 #include <GlobalContextManager.h>
25 #include <ArgumentValidator.h>
26 #include <Commons/Exception.h>
27 #include <CommonsJavaScript/PrivateObject.h>
28 #include <CommonsJavaScript/JSUtils.h>
29 #include <JSTizenExceptionFactory.h>
30 #include <JSTizenException.h>
31 #include <SecurityExceptions.h>
32 #include <JSWebAPIException.h>
33 #include <PlatformException.h>
34
35 #include "NFCFactory.h"
36 #include "plugin_config.h"
37 #include <Logger.h>
38
39 using namespace DeviceAPI::Common;
40 using namespace WrtDeviceApis::Commons;
41 using namespace WrtDeviceApis::CommonsJavaScript;
42
43 #define TIZEN_NDEFMESSAGE_ATTRIBUTENAME "NDEFMessage"
44 #define TIZEN_NDEFMESSAGE_RECORDCOUNT "recordCount"
45 #define TIZEN_NDEFMESSAGE_RECORDS "records"
46
47 namespace DeviceAPI {
48 namespace NFC {
49
50  JSClassDefinition JSNdefMessage::m_classInfo =
51 {
52     0,
53     kJSClassAttributeNone,
54     TIZEN_NDEFMESSAGE_ATTRIBUTENAME,
55     0,
56     m_property,
57     m_function,
58     initialize,
59     finalize,
60     NULL, //hasProperty,
61     NULL,
62     setProperty, //setProperty,
63     NULL, //DeleteProperty,
64     NULL, //GetPropertyNames,
65     NULL, //CallAsFunction,
66     NULL, //CallAsConstructor,
67     NULL, //HasInstance,
68     NULL  //ConvertToType
69 };
70
71 JSStaticValue JSNdefMessage::m_property[] =
72 {
73     //NdefMessageProperties
74     { TIZEN_NDEFMESSAGE_RECORDCOUNT, getProperty,
75             NULL, kJSPropertyAttributeReadOnly},
76      { TIZEN_NDEFMESSAGE_RECORDS, getProperty,
77             setProperty, kJSPropertyAttributeNone},
78     { 0, 0, 0, 0 }
79 };
80
81 JSStaticFunction JSNdefMessage::m_function[] = {
82     {"toByte", JSNdefMessage::toByte, kJSPropertyAttributeNone},
83     { 0, 0, 0}
84 };
85
86 JSClassRef JSNdefMessage::m_jsClassRef = JSClassCreate(JSNdefMessage::getClassInfo());
87
88 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, void *messageHandle) {
89         LoggerD("entered");
90
91         INdefMessagePtr ndefMessage = NFCFactory::getInstance().createNDEFMessageObject(messageHandle);
92         return createJSObject(context, ndefMessage);
93 }
94
95 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context) {
96         LoggerD("entered");
97
98         INdefMessagePtr ndefMessage = NFCFactory::getInstance().createNDEFMessageObject();
99         return createJSObject(context, ndefMessage);
100 }
101
102 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, INdefMessagePtr message) {
103         LoggerD("entered");
104
105         NFCConverter convert(context);
106         JSValueRef records = convert.toJSNdefRecordArray(message);
107         JSValueProtect(context, records);
108         message->setRecordesPtr((void*)records);
109         NdefMessagePrivObject *priv = new NdefMessagePrivObject(context, message);
110
111         if (!priv) {
112                 ThrowMsg(NullPointerException, "Can not new a NdefMessage object");
113         }
114
115         JSObjectRef obj = JSObjectMake(context, getClassRef(), priv);
116         return obj;
117 }
118
119 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, std::vector<void *> ndefRcords) {
120         LoggerD("entered");
121
122         INdefMessagePtr ndefMessage = NFCFactory::getInstance().createNDEFMessageObject(ndefRcords);
123         return createJSObject(context, ndefMessage);
124 }
125
126 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, std::vector<unsigned char> rawdata) {
127         LoggerD("entered");
128
129         INdefMessagePtr ndefMessage = NFCFactory::getInstance().createNDEFMessageObject(rawdata);
130         return createJSObject(context, ndefMessage);
131 }
132 void JSNdefMessage::initialize(JSContextRef context, JSObjectRef object)
133 {
134         LoggerD("entered");
135 }
136
137 void JSNdefMessage::finalize(JSObjectRef object)
138 {
139         LoggerD( "entered" );
140         NdefMessagePrivObject *priv = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(object));
141         if (priv) {
142                 INdefMessagePtr ndefMessage(priv->getObject());
143                 LoggerD("getRecordesPtr:"<<ndefMessage->getRecordesPtr());
144                 JSValueUnprotect(priv->getContext(), (JSValueRef)(ndefMessage->getRecordesPtr()));
145                 JSObjectSetPrivate(object, NULL);
146                 LoggerD("Deleting NdefMessage object");
147                 delete priv;
148         }
149 }
150
151
152 const JSClassRef JSNdefMessage::getClassRef()
153 {
154         if (!m_jsClassRef) {
155                 m_jsClassRef = JSClassCreate(&m_classInfo);
156         }
157         return m_jsClassRef;
158 }
159
160 const JSClassDefinition* JSNdefMessage::getClassInfo()
161 {
162         return &m_classInfo;
163 }
164
165 JSObjectRef JSNdefMessage::constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
166 {
167         LoggerD("entered");
168
169         Try {
170                 ArgumentValidator validator(ctx, argumentCount, arguments);
171         JSObjectRef objArg = validator.toArrayObject(0, true);
172                 JSObjectRef result = NULL;
173                 JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(ctx);
174
175                 if (objArg == NULL)
176                         result = createJSObject(global_context);
177                 else {
178                         NFCConverter convert(ctx);
179
180                         if (JSGetArrayLength(ctx, objArg) > 0) {
181                                 bool isRecordArray = false;
182                                 bool isByteArray = false;
183                                 for (std::size_t i = 0; i < JSGetArrayLength(ctx, objArg); ++i) {
184                                         JSValueRef element = JSGetArrayElement(ctx, objArg, i);
185                                         bool bNdefRecord = convert.isNdefRecord(element);
186                                         LoggerD("isNdefRecord : " << bNdefRecord);
187                                         if (bNdefRecord)
188                                                 isRecordArray = true;
189                                         else
190                                                 isByteArray = true;
191                                         if (isRecordArray && isByteArray)
192                                                 break;
193                                 }
194                                 if (isRecordArray && isByteArray)
195                                         ThrowMsg(ConversionException, "Parameter's type is not matched");
196                                 else if (isRecordArray)
197                                         result = createJSObject(global_context, convert.toVectorOfRecordHandles(objArg));
198                                 else
199                                         result = createJSObject(global_context, convert.toVectorOfUChars(arguments[0]));
200                                 
201                         } else
202                                 result = createJSObject(global_context);
203                 }
204                 if (result) {
205                         JSStringRef ctorName = JSStringCreateWithUTF8CString("constructor");
206                     JSObjectSetProperty(global_context, result, ctorName, constructor,
207                         kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete | kJSPropertyAttributeDontEnum, NULL);
208                 JSStringRelease(ctorName);
209                         return result;
210                 } else
211                         throw TypeMismatchException("Parameter Type Mismatch");
212         } Catch(BasePlatformException){
213                 JSObjectRef error = JSWebAPIException::makeJSWebAPIException(ctx, _rethrown_exception);
214         *exception = error;
215         return error;
216         } Catch(ConversionException) {
217                 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
218                 *exception = error;
219                 return error;
220         } Catch (InvalidArgumentException) {
221                 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
222                 *exception = error;
223                 return error;
224         } Catch (PlatformException) {
225                 JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available");
226                 *exception = error;
227                 return error;
228         } Catch (WrtDeviceApis::Commons::UnknownException) {
229                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
230         } Catch (WrtDeviceApis::Commons::Exception) {
231                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
232         }
233         JSObjectRef error = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
234         *exception = error;
235         return error;
236 }
237
238 JSValueRef JSNdefMessage::getProperty(JSContextRef context, JSObjectRef object,
239         JSStringRef propertyName, JSValueRef* exception)
240 {
241         LoggerD("Enter");
242
243         Try     {
244                 NdefMessagePrivObject* privateObject = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(object));
245                 if (!privateObject) {
246                         LoggerE("Private object is not set.");
247                         ThrowMsg(NullPointerException, "Private object not initialized");
248                 }
249
250                 INdefMessagePtr ndefMessage(privateObject->getObject());
251                 NFCConverter convert(context);
252
253                 LoggerD("propertyName : " << convert.toString(propertyName));
254                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NDEFMESSAGE_RECORDCOUNT)) {
255                         std::vector<void *> records = convert.toVectorOfRecordHandles(static_cast<JSValueRef>(ndefMessage->getRecordesPtr()));
256                         return convert.toJSValueRefLong(records.size());
257                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NDEFMESSAGE_RECORDS)) {
258                         return static_cast<JSValueRef>(ndefMessage->getRecordesPtr());
259                 }
260         } Catch (ConversionException) {
261                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
262         } Catch (NullPointerException) {
263                 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
264         } Catch (WrtDeviceApis::Commons::UnknownException) {
265                 LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
266         } Catch (PlatformException) {
267                 LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
268         } Catch (WrtDeviceApis::Commons::Exception) {
269                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
270         }
271         return JSValueMakeUndefined(context);
272 }
273
274 bool JSNdefMessage::setProperty(JSContextRef context, JSObjectRef object,
275         JSStringRef propertyName, JSValueRef value,  JSValueRef* exception)
276 {
277         LoggerD("Enter");
278
279         Try     {
280                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NDEFMESSAGE_RECORDS)) {
281                         NdefMessagePrivObject* privateObject = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(object));
282                         if (!privateObject) {
283                                 LoggerE("Private object is not set.");
284                                 ThrowMsg(NullPointerException, "Private object not initialized");
285                         }
286
287                         NFCConverter convert(context);
288
289
290                         if (JSValueIsNull(context, value) || JSValueIsUndefined(context, value) || !JSIsArrayValue(context, value)) {
291                                 LoggerE("value is invald.");
292                                 ThrowMsg(ConversionException, "value is invald.");
293                         }
294                         INdefMessagePtr ndefMessage(privateObject->getObject());
295                         JSValueUnprotect(privateObject->getContext(), (JSValueRef)ndefMessage->getRecordesPtr());
296                         JSValueProtect(privateObject->getContext(), value);
297                         ndefMessage->setRecordesPtr((void *)value);
298
299                         return true;
300                  }
301         } Catch (NullPointerException) {
302                 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
303         } Catch (ConversionException) {
304                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
305         } Catch (InvalidArgumentException) {
306                 LoggerE("InvalidArgumentException: " << _rethrown_exception.GetMessage());
307         } Catch (PlatformException) {
308                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
309         } Catch (WrtDeviceApis::Commons::UnknownException) {
310                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
311         } Catch (WrtDeviceApis::Commons::Exception) {
312                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
313         }
314         return false;
315
316 }
317
318 JSValueRef JSNdefMessage::toByte(JSContextRef context,
319         JSObjectRef object,
320         JSObjectRef thisObject,
321         size_t argumentCount,
322         const JSValueRef arguments[],
323         JSValueRef* exception)
324 {
325         LoggerD("Entered ");
326         Try {
327                 NdefMessagePrivObject* privateObject = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(thisObject));
328                 if (NULL == privateObject) {
329                         LoggerE("private object is null");
330                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
331                 }
332
333                 INdefMessagePtr ndefMessage(privateObject->getObject());
334                 NFCConverter convert(context);
335
336                 std::vector<void *> records = convert.toVectorOfRecordHandles(static_cast<JSValueRef>(ndefMessage->getRecordesPtr()));
337                 INdefMessagePtr newMessage = NFCFactory::getInstance().createNDEFMessageObject(records);
338                 return convert.toJSValueRef(newMessage->toByte());
339         } Catch (ConversionException) {
340                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
341                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
342         } Catch (WrtDeviceApis::Commons::UnknownException) {
343                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
344         } Catch (PlatformException) {
345                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
346                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available");
347         } Catch(NullPointerException) {
348                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
349                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
350         } Catch (WrtDeviceApis::Commons::Exception) {
351                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
352         }
353
354         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
355 }
356
357 }
358 }