db7e698d3564945c793df456ceb6ad489c8a88cf
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / NFC / JSNdefMessage.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include "JSNdefMessage.h"
19 #include "JSNdefRecord.h"
20 #include "JSNdefRecordText.h"
21 #include "JSNdefRecordURI.h"
22 #include "JSNdefRecordMedia.h"
23 #include "JSNdefRecordArray.h"
24 #include "NFCConverter.h"
25
26 #include <dpl/log/log.h>
27
28 #include <Commons/Exception.h>
29 #include <CommonsJavaScript/PrivateObject.h>
30 #include <CommonsJavaScript/JSUtils.h>
31 #include <Tizen/Common/JSTizenExceptionFactory.h>
32 #include <Tizen/Common/JSTizenException.h>
33 #include <Tizen/Common/SecurityExceptions.h>
34 #include <API/NFC/NFCFactory.h>
35 #include "plugin_config.h"
36
37 using namespace TizenApis::Api::NFC;
38 using namespace TizenApis::Commons;
39 using namespace WrtDeviceApis::Commons;
40 using namespace WrtDeviceApis::CommonsJavaScript;
41
42 #define TIZEN10_NDEFMESSAGE_ATTRIBUTENAME "NDEFMessage"
43 #define TIZEN10_NDEFMESSAGE_RECORDCOUNT "recordCount"
44 #define TIZEN10_NDEFMESSAGE_RECORDS "records"
45
46 namespace TizenApis {
47 namespace Tizen1_0 {
48
49  JSClassDefinition JSNdefMessage::m_classInfo =
50 {
51     0,
52     kJSClassAttributeNone,
53     TIZEN10_NDEFMESSAGE_ATTRIBUTENAME,
54     0,
55     m_property,
56     m_function,
57     initialize,
58     finalize,
59     NULL, //hasProperty,
60     NULL,
61     setProperty, //setProperty,
62     NULL, //DeleteProperty,
63     NULL, //GetPropertyNames,
64     NULL, //CallAsFunction,
65     constructor, //CallAsConstructor,
66     hasInstance, //HasInstance,
67     NULL  //ConvertToType
68 };
69
70 JSStaticValue JSNdefMessage::m_property[] =
71 {
72     //NdefMessageProperties
73     { TIZEN10_NDEFMESSAGE_RECORDCOUNT, getProperty,
74             NULL, kJSPropertyAttributeReadOnly},
75      { TIZEN10_NDEFMESSAGE_RECORDS, getProperty,
76             setProperty, kJSPropertyAttributeNone},
77     { 0, 0, 0, 0 }
78 };
79
80 JSStaticFunction JSNdefMessage::m_function[] = {
81     {"toByte", JSNdefMessage::toByte, kJSPropertyAttributeNone},
82     { 0, 0, 0}
83 };
84
85 JSClassRef JSNdefMessage::m_jsClassRef = JSClassCreate(JSNdefMessage::getClassInfo());
86
87 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, void *messageHandle) {
88         LogDebug("entered");
89
90         INdefMessagePtr NdefMessage = NFCFactory::getInstance().createNDEFMessageObject(messageHandle);
91
92         NdefMessagePrivObject *priv = new NdefMessagePrivObject(context, NdefMessage);
93
94         if (!priv) {
95                 ThrowMsg(NullPointerException, "Can not new a NdefMessage object");
96         }
97
98         return JSObjectMake(context, getClassRef(), priv);
99 }
100
101 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context) {
102         LogDebug("entered");
103
104         INdefMessagePtr NdefMessage = NFCFactory::getInstance().createNDEFMessageObject();
105
106         NdefMessagePrivObject *priv = new NdefMessagePrivObject(context, NdefMessage);
107
108         if (!priv) {
109                 ThrowMsg(NullPointerException, "Can not new a NdefMessage object");
110         }
111
112         return JSObjectMake(context, getClassRef(), priv);
113 }
114
115 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, INdefMessagePtr message) {
116         LogDebug("entered");
117
118         NdefMessagePrivObject *priv = new NdefMessagePrivObject(context, message);
119
120         if (!priv) {
121                 ThrowMsg(NullPointerException, "Can not new a NdefMessage object");
122         }
123
124         return JSObjectMake(context, getClassRef(), priv);
125 }
126
127 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, std::vector<void *> ndefRcords) {
128         LogDebug("entered");
129
130         INdefMessagePtr NdefMessage = NFCFactory::getInstance().createNDEFMessageObject(ndefRcords);
131
132         NdefMessagePrivObject *priv = new NdefMessagePrivObject(context, NdefMessage);
133
134         if (!priv) {
135                 ThrowMsg(NullPointerException, "Can not new a NdefMessage object");
136         }
137
138         return JSObjectMake(context, getClassRef(), priv);
139 }
140
141 JSObjectRef JSNdefMessage::createJSObject(JSContextRef context, std::vector<unsigned char> rawdata) {
142         LogDebug("entered");
143
144         INdefMessagePtr NdefMessage = NFCFactory::getInstance().createNDEFMessageObject(rawdata);
145
146         NdefMessagePrivObject *priv = new NdefMessagePrivObject(context, NdefMessage);
147
148         if (!priv) {
149                 ThrowMsg(NullPointerException, "Can not new a NdefMessage object");
150         }
151
152         return JSObjectMake(context, getClassRef(), priv);
153 }
154 void JSNdefMessage::initialize(JSContextRef context, JSObjectRef object)
155 {
156         LogDebug("entered");
157
158         if (!JSObjectGetPrivate(object)) {
159                 LogDebug("Private object not set... setting it.");
160                 INdefMessagePtr NdefMessage = NFCFactory::getInstance().createNDEFMessageObject();
161                 NdefMessagePrivObject *priv = new NdefMessagePrivObject(context, NdefMessage);
162                 if (!JSObjectSetPrivate(object, priv)) {
163                         delete priv;
164                 }
165         }
166 }
167
168 void JSNdefMessage::finalize(JSObjectRef object)
169 {
170         LogDebug( "entered" );
171         NdefMessagePrivObject *priv = static_cast<NdefMessagePrivObject*>( JSObjectGetPrivate( object ) ) ;
172         JSObjectSetPrivate(object, NULL);
173         LogDebug("Deleting NdefMessage object");
174         delete priv;
175 }
176
177
178 const JSClassRef JSNdefMessage::getClassRef()
179 {
180         if (!m_jsClassRef) {
181                 m_jsClassRef = JSClassCreate(&m_classInfo);
182         }
183         return m_jsClassRef;
184 }
185
186 const JSClassDefinition* JSNdefMessage::getClassInfo()
187 {
188         return &m_classInfo;
189 }
190
191 JSObjectRef JSNdefMessage::constructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
192 {
193         LogDebug("entered");
194
195         NdefMessagePrivObject* mainPriv = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(constructor));
196         JSContextRef global_context = mainPriv ? mainPriv->getContext() : ctx;
197         Try {
198                 if (argumentCount == 0)
199                         return createJSObject(global_context);
200                 else if (argumentCount == 1) {
201                         if (JSValueIsNull(ctx, arguments[0]) || JSValueIsUndefined(ctx, arguments[0]) || !(JSIsArrayValue(ctx, arguments[0]) || JSNdefRecordArray::isObjectOfClass(ctx, arguments[0])))
202                                 ThrowMsg(ConversionException, "Parameter's type is not matched");
203
204                         NFCConverter convert(ctx);
205
206                         if (JSNdefRecordArray::isObjectOfClass(ctx, arguments[0])) {
207                                 return createJSObject(global_context, JSNdefRecordArray::getNdefRecordArray(ctx, arguments[0]));
208                         }
209
210                         JSObjectRef objArg = convert.toJSObjectRef(arguments[0]);
211                         if (JSGetArrayLength(ctx, objArg) > 0) {
212                                 JSValueRef element;
213                                 for (std::size_t i = 0; i < JSGetArrayLength(ctx, objArg); ++i) {
214                                         element = JSGetArrayElement(ctx, objArg, i);
215                                         if (!JSValueIsNull(ctx, element))
216                                                 break;
217                                 }
218                                 if (JSValueIsNull(ctx, element))
219                                         return createJSObject(global_context);
220                                 else if (convert.isNdefRecord(element))
221                                         return createJSObject(global_context, convert.toVectorOfRecordHandles(arguments[0]));
222                                 else
223                                         return createJSObject(global_context, convert.toVectorOfUChars(arguments[0]));
224                         } else
225                                 return createJSObject(global_context);
226                 }
227                 else
228                         ThrowMsg(InvalidArgumentException, "ArgumentCount is not correct");
229
230         } Catch(ConversionException) {
231                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
232                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
233                 return NULL;
234         } Catch (InvalidArgumentException) {
235                 LogError("InvalidArgumentException: " << _rethrown_exception.GetMessage());
236                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
237                 return NULL;
238         } Catch (PlatformException) {
239                 LogError("PlatformException: " << _rethrown_exception.GetMessage());
240                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
241                 return NULL;
242         } Catch (WrtDeviceApis::Commons::Exception) {
243                 LogError("Exception: " << _rethrown_exception.GetMessage());
244                 *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
245                 return NULL;
246         }
247         *exception = JSTizenExceptionFactory::makeErrorObject(ctx, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
248         return NULL;
249 }
250
251 JSValueRef JSNdefMessage::getProperty(JSContextRef context, JSObjectRef object,
252         JSStringRef propertyName, JSValueRef* exception)
253 {
254         LogDebug("Enter");
255
256         Try     {
257                 NdefMessagePrivObject* privateObject = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(object));
258                 if (!privateObject) {
259                         LogError("Private object is not set.");
260                         ThrowMsg(NullPointerException, "Private object not initialized");
261                 }
262
263                 INdefMessagePtr NdefMessage(privateObject->getObject());
264                 NFCConverter convert(context);
265
266                 LogDebug("propertyName : " << convert.toString(propertyName));
267                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN10_NDEFMESSAGE_RECORDCOUNT)) {
268                         return convert.toJSValueRefLong(NdefMessage->getRecordCount());
269                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN10_NDEFMESSAGE_RECORDS)) {
270                         return JSNdefRecordArray::createArray(privateObject->getContext(), NdefMessage);
271                 }
272         } Catch (ConversionException) {
273                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
274         } Catch (NullPointerException) {
275                 LogError("NullPointerException: " << _rethrown_exception.GetMessage());
276         } Catch (WrtDeviceApis::Commons::Exception) {
277                 LogError("Exception: " << _rethrown_exception.GetMessage());
278         }
279         return JSValueMakeUndefined(context);
280 }
281
282 bool JSNdefMessage::setProperty(JSContextRef context, JSObjectRef object,
283         JSStringRef propertyName, JSValueRef value,  JSValueRef* exception)
284 {
285         LogDebug("Enter");
286
287         Try     {
288                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN10_NDEFMESSAGE_RECORDS)) {
289                         NdefMessagePrivObject* privateObject = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(object));
290                         if (!privateObject) {
291                                 LogError("Private object is not set.");
292                                 ThrowMsg(NullPointerException, "Private object not initialized");
293                         }
294
295                         INdefMessagePtr NdefMessage(privateObject->getObject());
296                         NFCConverter convert(context);
297
298                         if (JSValueIsNull(context, value) || JSValueIsUndefined(context, value) || !(JSIsArrayValue(context, value) || JSNdefRecordArray::isObjectOfClass(context, value))) {
299                                 LogError("value is invald.");
300                                 ThrowMsg(ConversionException, "value is invald.");
301                         }
302
303                         NdefMessagePrivObject *priv;
304                         if (JSNdefRecordArray::isObjectOfClass(context, value))
305                                 priv = new NdefMessagePrivObject(context, JSNdefRecordArray::getNdefRecordArray(context, value));
306                         else {
307                                 std::vector<void *> records = convert.toVectorOfRecordHandles(value);
308                                 priv = new NdefMessagePrivObject(context, NFCFactory::getInstance().createNDEFMessageObject(records));
309                         }
310                         if (!JSObjectSetPrivate(object, priv)) {
311                                 delete priv;
312                                         ThrowMsg(NullPointerException, "Private object not set");
313                         }
314                         delete privateObject;
315                         return true;
316                  }
317         } Catch (NullPointerException) {
318                 LogError("NullPointerException: " << _rethrown_exception.GetMessage());
319                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
320         } Catch (ConversionException) {
321                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
322                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
323         } Catch (InvalidArgumentException) {
324                 LogError("InvalidArgumentException: " << _rethrown_exception.GetMessage());
325                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
326         } Catch (WrtDeviceApis::Commons::Exception) {
327                 LogError("Exception: " << _rethrown_exception.GetMessage());
328                 *exception = JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
329         }
330         return false;
331
332 }
333
334 bool JSNdefMessage::hasInstance(JSContextRef context,
335         JSObjectRef constructor,
336         JSValueRef possibleInstance,
337         JSValueRef* exception)
338 {
339     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
340 }
341
342 JSValueRef JSNdefMessage::toByte(JSContextRef context,
343         JSObjectRef object,
344         JSObjectRef thisObject,
345         size_t argumentCount,
346         const JSValueRef arguments[],
347         JSValueRef* exception)
348 {
349         LogDebug("Entered ");
350         Try {
351                 if (argumentCount != 0) {
352                         LogError("JSNdefMessage::toByte TypeMismatchException");
353                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values");
354                 }
355
356                 NdefMessagePrivObject* privateObject = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(thisObject));
357                 if (NULL == privateObject) {
358                         LogError("private object is null");
359                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
360                 }
361
362                 AceSecurityStatus status = NFC_CHECK_ACCESS(privateObject->getContext(),NFC_FUNCTION_API_TAG_P2P_FUNCS);
363                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
364
365                 INdefMessagePtr NdefMessage(privateObject->getObject());
366                 NFCConverter convert(context);
367
368                 return convert.toJSValueRef(NdefMessage->toByte());
369         } Catch (PlatformException) {
370                 LogError("Exception: " << _rethrown_exception.GetMessage());
371                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
372         } Catch(NullPointerException) {
373                 LogError("Exception: " << _rethrown_exception.GetMessage());
374                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
375         } Catch (WrtDeviceApis::Commons::Exception) {
376                 LogError("Exception: " << _rethrown_exception.GetMessage());
377                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
378         }
379
380         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
381 }
382
383 }
384 }