Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Tizen / JSAbstractFilterArray.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  * @file        JSAbstractFilterArray.cpp
19  * @author      Kisub Song (kisubs.song@samsung.com)
20  * @version     0.1
21  * @brief
22  */
23
24 #include <algorithm>
25 #include <dpl/log/log.h>
26 #include <CommonsJavaScript/ScopedJSStringRef.h>
27 #include <Tizen/Common/JSTizenExceptionFactory.h>
28 #include <Tizen/Common/JSTizenException.h>
29 #include "FilterConverter.h"
30 #include "JSAbstractFilterArray.h"
31
32 #define FUNCTION_CONCAT "concat"
33 #define FUNCTION_JOIN "join"
34 #define FUNCTION_POP "pop"
35 #define FUNCTION_PUSH "push"
36 #define FUNCTION_REVERSE "reverse"
37 #define FUNCTION_SHIFT "shift"
38 #define FUNCTION_SLICE "slice"
39 #define FUNCTION_SORT "sort"
40 #define FUNCTION_SPLICE "splice"
41 #define FUNCTION_TOSTRING "toString"
42 #define FUNCTION_UNSHIFT "unshift"
43 #define FUNCTION_VALUEOF "valueOf"
44 #define ARRAY "Array"
45 #define ATTRIBUTE_LENGTH "length"
46 #define FUNCTION_CONSTRUCTOR "constructor"
47
48 namespace TizenApis {
49 namespace Tizen1_0 {
50 namespace Tizen {
51
52 using namespace TizenApis::Commons;
53 using namespace TizenApis::Api::Tizen;
54
55 JSClassDefinition JSAbstractFilterArray::m_classInfo = {
56         0,
57         kJSClassAttributeNone,
58         ARRAY,
59         0,
60         m_property,
61         m_function,
62         initialize,
63         finalize,
64         hasProperty,
65         getProperty,
66         setProperty,
67         NULL, //deleteProperty,
68         NULL, //getPropertyNames,
69         NULL, //callAsFunction,
70         NULL, //callAsConstructor,
71         NULL, //hasInstance,
72         NULL, //convertToType,
73 };
74
75 JSStaticValue JSAbstractFilterArray::m_property[] = {
76         { ATTRIBUTE_LENGTH, getLength, NULL, kJSPropertyAttributeReadOnly },
77         { 0, 0, 0, 0 }
78 };
79
80 JSStaticFunction JSAbstractFilterArray::m_function[] = {
81         { FUNCTION_CONCAT, concat, kJSPropertyAttributeNone },
82         { FUNCTION_JOIN, join, kJSPropertyAttributeNone },
83         { FUNCTION_POP, pop, kJSPropertyAttributeNone },
84         { FUNCTION_PUSH, push, kJSPropertyAttributeNone },
85         { FUNCTION_REVERSE, reverse, kJSPropertyAttributeNone },
86         { FUNCTION_SHIFT, shift, kJSPropertyAttributeNone },
87         { FUNCTION_SLICE, slice, kJSPropertyAttributeNone },
88         { FUNCTION_SORT, sort, kJSPropertyAttributeNone },
89         { FUNCTION_SPLICE, splice, kJSPropertyAttributeNone },
90         { FUNCTION_TOSTRING, toString, kJSPropertyAttributeNone },
91         { FUNCTION_UNSHIFT, unshift, kJSPropertyAttributeNone },
92         { FUNCTION_VALUEOF, valueOf, kJSPropertyAttributeNone },
93         { FUNCTION_CONSTRUCTOR, constructor, kJSPropertyAttributeNone },
94         { 0, 0, 0 }
95 };
96
97 JSClassRef JSAbstractFilterArray::m_jsClassRef = JSClassCreate(
98                 JSAbstractFilterArray::getClassInfo());
99
100 JSValueRef JSAbstractFilterArray::getLength(JSContextRef context,
101                 JSObjectRef object,
102                 JSStringRef propertyName,
103                 JSValueRef* exception)
104 {
105         //LogDebug("enter");
106         Try
107         {
108                 JSAbstractFilterArrayPriv* priv =
109                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(object));
110                 if (!priv) {
111                         Throw(WrtDeviceApis::Commons::NullPointerException);
112                 }
113                 FilterArrayPtr filters = priv->getObject();
114                 if (filters) {
115                         FilterConverterFactory::ConverterType converter =
116                                         FilterConverterFactory::getConverter(context);
117                         return converter->toJSValueRef(filters->size());
118                 }
119         }
120         Catch(WrtDeviceApis::Commons::Exception)
121         {
122                 LogError("invalid conversion");
123         }
124         return JSValueMakeUndefined(context);
125 }
126
127 bool JSAbstractFilterArray::isObjectOfClass(JSContextRef context, JSValueRef value)
128 {
129         return JSValueIsObjectOfClass(context, value, getClassRef());
130 }
131
132 FilterArrayPtr JSAbstractFilterArray::getAbstractFilterArray(JSContextRef context, JSValueRef value)
133 {
134         if (!isObjectOfClass(context, value)) {
135                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
136         }
137         JSObjectRef object = JSValueToObject(context, value, NULL);
138         if (!object) {
139                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
140         }
141         JSAbstractFilterArrayPriv *priv = static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(object));
142         if (!priv) {
143                 Throw(WrtDeviceApis::Commons::NullPointerException);
144         }
145         return priv->getObject();
146 }
147
148 JSObjectRef JSAbstractFilterArray::createArray(JSContextRef context,
149                 const FilterArrayPtr &filters)
150 {
151         JSAbstractFilterArrayPriv *priv = new JSAbstractFilterArrayPriv(context, filters);
152         return JSObjectMake(context, getClassRef(), priv);
153 }
154
155 const JSClassDefinition* JSAbstractFilterArray::getClassInfo()
156 {
157         return &(m_classInfo);
158 }
159
160 JSClassRef JSAbstractFilterArray::getClassRef()
161 {
162         if (!m_jsClassRef) {
163                 m_jsClassRef = JSClassCreate(&m_classInfo);
164         }
165         return m_jsClassRef;
166 }
167
168 void JSAbstractFilterArray::initialize(JSContextRef context,
169                 JSObjectRef object)
170 {
171         //LogDebug("enter");
172 }
173
174 void JSAbstractFilterArray::finalize(JSObjectRef object)
175 {
176         //LogDebug("enter");
177         JSAbstractFilterArrayPriv* priv =
178                 static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(object));
179         delete priv;
180         JSObjectSetPrivate(object, NULL);
181 }
182
183 bool JSAbstractFilterArray::hasProperty(JSContextRef context,
184                 JSObjectRef object,
185                 JSStringRef propertyName)
186 {
187         //LogDebug("enter");
188         FilterConverterFactory::ConverterType converter =
189                         FilterConverterFactory::getConverter(context);
190         Try
191         {
192                 size_t index = converter->toSizeT(propertyName);
193                 JSAbstractFilterArrayPriv* priv =
194                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(object));
195                 if (!priv) {
196                         Throw(WrtDeviceApis::Commons::NullPointerException);
197                 }
198                 FilterArrayPtr filters = priv->getObject();
199                 if (index < filters->size()) {
200                         return true;
201                 }
202         }
203         Catch(WrtDeviceApis::Commons::Exception)
204         {
205                 //not reporting error is intended
206         }
207         return false;
208 }
209
210 JSValueRef JSAbstractFilterArray::getProperty(JSContextRef context,
211                 JSObjectRef object,
212                 JSStringRef propertyName,
213                 JSValueRef* exception)
214 {
215         //LogDebug("enter");
216         FilterConverterFactory::ConverterType converter =
217                         FilterConverterFactory::getConverter(context);
218         Try
219         {
220                 size_t index = converter->toSizeT(propertyName);
221                 JSAbstractFilterArrayPriv* priv =
222                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(object));
223                 if (!priv) {
224                         Throw(WrtDeviceApis::Commons::NullPointerException);
225                 }
226                 FilterArrayPtr filters = priv->getObject();
227                 if (index < filters->size()) {
228                         FilterPtr result = filters->at(index);
229                         if (result) {
230                                 return converter->toJSValueRef(result);
231                         }
232                 }
233         }
234         Catch(WrtDeviceApis::Commons::Exception)
235         {
236                 LogError("invalid property");
237         }
238         return JSValueMakeUndefined(context);
239 }
240
241 bool JSAbstractFilterArray::setProperty(JSContextRef context,
242                 JSObjectRef object,
243                 JSStringRef propertyName,
244                 JSValueRef value,
245                 JSValueRef* exception)
246 {
247         //LogDebug("enter");
248         FilterConverterFactory::ConverterType converter =
249                         FilterConverterFactory::getConverter(context);
250         Try
251         {
252                 size_t index = converter->toSizeT(propertyName);
253                 FilterPtr filter;
254                 if (!JSValueIsUndefined(context, value)) {
255                         filter = converter->toFilter(value);
256                 }
257                 JSAbstractFilterArrayPriv* priv =
258                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(object));
259                 if (!priv) {
260                         Throw(WrtDeviceApis::Commons::NullPointerException);
261                 }
262                 FilterArrayPtr filters = priv->getObject();
263                 if (!filters) {
264                         Throw(WrtDeviceApis::Commons::NullPointerException);
265                 }
266                 if (filters->size() <= index) {
267                         filters->resize(index + 1);
268                 }
269                 (*filters)[index] = filter;
270                 return true;
271         }
272         Catch(WrtDeviceApis::Commons::Exception)
273         {
274                 LogError("error occured");
275                 JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
276         }
277         return false;
278 }
279
280 JSValueRef JSAbstractFilterArray::concat(JSContextRef context,
281                 JSObjectRef function,
282                 JSObjectRef thisObject,
283                 size_t argumentCount,
284                 const JSValueRef arguments[],
285                 JSValueRef* exception)
286 {
287         //LogDebug("enter");
288         Try
289         {
290                 FilterArrayPtr filters = FilterArrayPtr(new FilterArray());
291                 JSAbstractFilterArrayPriv *newPrivateObject = new JSAbstractFilterArrayPriv(context, filters);
292                 JSValueRef result = JSObjectMake(context, getClassRef(), newPrivateObject);
293
294                 //copy current filters
295                 JSAbstractFilterArrayPriv* priv =
296                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
297                 FilterArrayPtr currentWebSites = priv->getObject();
298                 for (size_t i = 0; i < currentWebSites->size(); ++i) {
299                         filters->push_back(currentWebSites->at(i));
300                 }
301
302                 //copy submitted arrays
303                 FilterConverterFactory::ConverterType converter =
304                                 FilterConverterFactory::getConverter(context);
305                 for (size_t i = 0; i < argumentCount; ++i) {
306                         if (!JSIsArrayValue(context, arguments[i])) {
307                                 Throw(WrtDeviceApis::Commons::ConversionException);
308                         }
309                         // process array of strings
310                         JSObjectRef arrayObj = converter->toJSObjectRef(arguments[i]);
311                         unsigned int len = JSGetArrayLength(context, arrayObj);
312                         for (unsigned int e = 0; e < len; ++e) {
313                                 JSValueRef att = JSGetArrayElement(context, arrayObj, e);
314                                 filters->push_back(converter->toFilter(att));
315                         }
316                 }
317                 return result;
318         }
319         Catch(WrtDeviceApis::Commons::Exception)
320         {
321                 LogError("error occured");
322         }
323         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
324 }
325
326 JSValueRef JSAbstractFilterArray::join(JSContextRef context,
327                 JSObjectRef function,
328                 JSObjectRef thisObject,
329                 size_t argumentCount,
330                 const JSValueRef arguments[],
331                 JSValueRef* exception)
332 {
333         //LogDebug("entered");
334         Try
335         {
336                 std::string result;
337                 std::string separator(",");
338                 FilterConverterFactory::ConverterType converter =
339                                 FilterConverterFactory::getConverter(context);
340                 JSAbstractFilterArrayPriv* priv =
341                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
342                 FilterArrayPtr currentWebSites = priv->getObject();
343                 if (argumentCount > 0 && JSValueIsString(context, arguments[0])) {
344                         separator = converter->toString(arguments[0]);
345                 }
346                 for (size_t i = 0; i < currentWebSites->size(); ++i) {
347                         if (i != 0) {
348                                 result += separator;
349                         }
350                         //FIXME : to be changed to support join
351                         //result += currentWebSites->at(i);
352                 }
353                 return converter->toJSValueRef(result);
354         }
355         Catch(WrtDeviceApis::Commons::Exception)
356         {
357                 LogError("error occured");
358         }
359         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
360 }
361
362 JSValueRef JSAbstractFilterArray::pop(JSContextRef context,
363                 JSObjectRef function,
364                 JSObjectRef thisObject,
365                 size_t argumentCount,
366                 const JSValueRef arguments[],
367                 JSValueRef* exception)
368 {
369         //LogDebug("entered");
370         Try
371         {
372                 FilterConverterFactory::ConverterType converter =
373                                 FilterConverterFactory::getConverter(context);
374                 JSAbstractFilterArrayPriv* priv =
375                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
376                 FilterArrayPtr currentWebSites = priv->getObject();
377                 if (currentWebSites->size() > 0) {
378                         FilterPtr result = currentWebSites->at(
379                                         currentWebSites->size() - 1);
380                         currentWebSites->pop_back();
381                         return converter->toJSValueRef(result);
382                 }
383         }
384         Catch(WrtDeviceApis::Commons::Exception)
385         {
386                 LogError("error occured");
387         }
388         return JSValueMakeUndefined(context);
389 }
390
391 JSValueRef JSAbstractFilterArray::push(JSContextRef context,
392                 JSObjectRef function,
393                 JSObjectRef thisObject,
394                 size_t argumentCount,
395                 const JSValueRef arguments[],
396                 JSValueRef* exception)
397 {
398         //LogDebug("entered");
399         Try
400         {
401                 FilterConverterFactory::ConverterType converter =
402                                 FilterConverterFactory::getConverter(context);
403                 JSAbstractFilterArrayPriv* priv =
404                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
405                 FilterArrayPtr currentWebSites = priv->getObject();
406                 for (size_t i = 0; i < argumentCount; ++i) {
407                         currentWebSites->push_back(converter->toFilter(arguments[i]));
408                 }
409                 return converter->toJSValueRef(currentWebSites->size());
410         }
411         Catch(WrtDeviceApis::Commons::Exception)
412         {
413                 LogError("error occured");
414         }
415         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
416 }
417
418 JSValueRef JSAbstractFilterArray::reverse(JSContextRef context,
419                 JSObjectRef function,
420                 JSObjectRef thisObject,
421                 size_t argumentCount,
422                 const JSValueRef arguments[],
423                 JSValueRef* exception)
424 {
425         //LogDebug("entered");
426         Try
427         {
428                 FilterConverterFactory::ConverterType converter =
429                                 FilterConverterFactory::getConverter(context);
430                 JSAbstractFilterArrayPriv* priv =
431                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
432                 FilterArrayPtr currentWebSites = priv->getObject();
433                 std::reverse(currentWebSites->begin(), currentWebSites->end());
434                 return thisObject;
435         }
436         Catch(WrtDeviceApis::Commons::Exception)
437         {
438                 LogError("error occured");
439         }
440         return JSValueMakeUndefined(context);
441 }
442
443 JSValueRef JSAbstractFilterArray::shift(JSContextRef context,
444                 JSObjectRef function,
445                 JSObjectRef thisObject,
446                 size_t argumentCount,
447                 const JSValueRef arguments[],
448                 JSValueRef* exception)
449 {
450         //LogDebug("entered");
451         Try
452         {
453                 FilterConverterFactory::ConverterType converter =
454                                 FilterConverterFactory::getConverter(context);
455                 JSAbstractFilterArrayPriv* priv =
456                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
457                 FilterArrayPtr currentWebSites = priv->getObject();
458                 if (currentWebSites->size() > 0) {
459                         FilterPtr result = currentWebSites->at(0);
460                         currentWebSites->erase(currentWebSites->begin());
461                         return converter->toJSValueRef(result);
462                 }
463         }
464         Catch(WrtDeviceApis::Commons::Exception)
465         {
466                 LogError("error occured");
467         }
468         return JSValueMakeUndefined(context);
469 }
470
471 JSValueRef JSAbstractFilterArray::slice(JSContextRef context,
472                 JSObjectRef function,
473                 JSObjectRef thisObject,
474                 size_t argumentCount,
475                 const JSValueRef arguments[],
476                 JSValueRef* exception)
477 {
478         //LogDebug("enter");
479         Try
480         {
481                 if (argumentCount < 1) {
482                         return JSValueMakeUndefined(context);
483                 }
484                 FilterConverterFactory::ConverterType converter =
485                                 FilterConverterFactory::getConverter(context);
486                 FilterArrayPtr filters = FilterArrayPtr(new FilterArray());
487                 JSAbstractFilterArrayPriv *newPrivateObject = new JSAbstractFilterArrayPriv(
488                                 context,
489                                 filters);
490                 JSValueRef result = JSObjectMake(context,
491                                                                                  getClassRef(), newPrivateObject);
492
493                 //copy current filters
494                 JSAbstractFilterArrayPriv* priv =
495                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
496                 FilterArrayPtr currentWebSites = priv->getObject();
497                 std::size_t first = converter->toSizeT(arguments[0]);
498                 std::size_t last = currentWebSites->size() - 1;
499                 if (argumentCount > 1) {
500                         last = converter->toSizeT(arguments[1]);
501                         if (last >= currentWebSites->size()) {
502                                 last = currentWebSites->size() - 1;
503                         }
504                 }
505                 if (first < 0) {
506                         first = 0;
507                 }
508                 for (size_t i = first; i <= last; ++i) {
509                         filters->push_back(currentWebSites->at(i));
510                 }
511
512                 return result;
513         }
514         Catch(WrtDeviceApis::Commons::Exception)
515         {
516                 LogError("error occured");
517         }
518         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
519 }
520
521 JSValueRef JSAbstractFilterArray::sort(JSContextRef context,
522                 JSObjectRef function,
523                 JSObjectRef thisObject,
524                 size_t argumentCount,
525                 const JSValueRef arguments[],
526                 JSValueRef* exception)
527 {
528         //LogDebug("entered");
529         Try
530         {
531                 FilterConverterFactory::ConverterType converter =
532                                 FilterConverterFactory::getConverter(context);
533                 JSAbstractFilterArrayPriv* priv =
534                         static_cast<JSAbstractFilterArrayPriv*>(JSObjectGetPrivate(thisObject));
535                 FilterArrayPtr currentWebSites = priv->getObject();
536                 std::sort(currentWebSites->begin(), currentWebSites->end());
537                 return thisObject;
538         }
539         Catch(WrtDeviceApis::Commons::Exception)
540         {
541                 LogError("error occured");
542         }
543         return JSValueMakeUndefined(context);
544 }
545
546 JSValueRef JSAbstractFilterArray::splice(JSContextRef context,
547                 JSObjectRef function,
548                 JSObjectRef thisObject,
549                 size_t argumentCount,
550                 const JSValueRef arguments[],
551                 JSValueRef* exception)
552 {
553         //LogDebug("entered");
554         return JSValueMakeUndefined(context);
555 }
556
557 JSValueRef JSAbstractFilterArray::toString(JSContextRef context,
558                 JSObjectRef function,
559                 JSObjectRef thisObject,
560                 size_t argumentCount,
561                 const JSValueRef arguments[],
562                 JSValueRef* exception)
563 {
564         //LogDebug("entered");
565         return join(context, function, thisObject, 0, arguments, exception);
566 }
567
568 JSValueRef JSAbstractFilterArray::unshift(JSContextRef context,
569                 JSObjectRef function,
570                 JSObjectRef thisObject,
571                 size_t argumentCount,
572                 const JSValueRef arguments[],
573                 JSValueRef* exception)
574 {
575         //LogDebug("entered");
576         return JSValueMakeUndefined(context);
577 }
578
579 JSValueRef JSAbstractFilterArray::valueOf(JSContextRef context,
580                 JSObjectRef function,
581                 JSObjectRef thisObject,
582                 size_t argumentCount,
583                 const JSValueRef arguments[],
584                 JSValueRef* exception)
585 {
586         //LogDebug("entered");
587         return JSValueMakeUndefined(context);
588 }
589
590 JSValueRef JSAbstractFilterArray::constructor(JSContextRef context,
591                 JSObjectRef function,
592                 JSObjectRef thisObject,
593                 size_t argumentCount,
594                 const JSValueRef arguments[],
595                 JSValueRef* exception)
596 {
597         // To determine this object as array
598         WrtDeviceApis::CommonsJavaScript::ScopedJSStringRef json(JSStringCreateWithUTF8CString("[]"));
599         JSValueRef array = JSValueMakeFromJSONString(context, json.get());
600         WrtDeviceApis::CommonsJavaScript::ScopedJSStringRef constructorStr(JSStringCreateWithUTF8CString("constructor"));
601         JSObjectRef arrayObject = JSValueToObject(context, array, NULL);
602         JSValueRef constructorValue = JSObjectGetProperty(context, arrayObject, constructorStr.get(), NULL);
603         return constructorValue;
604 }
605
606 } // Contact
607 } // Tizen1_0
608 } // TizenApis