Update change log and spec for wrt-plugins-tizen_0.4.11
[framework/web/wrt-plugins-tizen.git] / src / Tizen / FilterConverter.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 /**
19  * @file        FilterConverter.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @description Reference from CalendarConverter.cpp
23  */
24
25 #include <dpl/log/log.h>
26 #include <CommonsJavaScript/ScopedJSStringRef.h>
27 #include <CommonsJavaScript/Validator.h>
28 #include <CommonsJavaScript/JSUtils.h>
29 #include "JSAttributeFilter.h"
30 #include "JSAttributeRangeFilter.h"
31 #include "JSCompositeFilter.h"
32 #include "JSSortMode.h"
33 #include "FilterConverter.h"
34
35 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_TYPE                           "type"
36 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_ORDER                          "order"
37 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_FILTERS                        "filters"
38 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_IDS                            "ids"
39 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_ATTRIBUTE_NAME         "attributeName"
40 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_MATCH_FLAG                     "matchFlag"
41 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_MATCH_VALUES           "matchValues"
42 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_INITIAL_VALUE          "initialValue"
43 #define TIZEN_FILTER_CONVERTER_ATTRIBUTE_END_VALUE                      "endValue"
44
45 namespace DeviceAPI {\rnamespace Tizen {
46
47 using namespace DeviceAPI::Tizen;
48 using namespace WrtDeviceApis::Commons;
49 using namespace WrtDeviceApis::CommonsJavaScript;
50
51 using namespace std;
52
53 FilterConverter::FilterConverter(JSContextRef context) : Converter(context)
54 {
55         initFilterAttrs();
56 }
57
58 FilterConverter::~FilterConverter()
59 {
60         LogDebug("entered");
61 }
62
63 JSValueRef FilterConverter::toJSValueRef(FilterPtr arg)
64 {
65         if(arg == NULL)
66                 ThrowMsg(NullPointerException, "Filter is NULL.");
67
68         JSValueRef result = NULL;
69
70         if(arg->getFilterType() == UNION_FILTER || arg->getFilterType() == INTERSECTION_FILTER)
71         {
72                 CompositeFilterPtr filter = DPL::DynamicPointerCast<CompositeFilter>(arg);
73
74                 result = toJSValueRef(filter);
75         }
76         else if(arg->getFilterType() == ATTRIBUTE_FILTER)
77         {
78                 AttributeFilterPtr filter = DPL::DynamicPointerCast<AttributeFilter>(arg);
79
80                 result = toJSValueRef(filter);
81         }
82         else if(arg->getFilterType() == ATTRIBUTE_RANGE_FILTER)
83         {
84                 AttributeRangeFilterPtr filter = DPL::DynamicPointerCast<AttributeRangeFilter>(arg);
85
86                 result = toJSValueRef(filter);
87         }
88
89         return result;
90 }
91
92 FilterPtr FilterConverter::toFilter(const JSValueRef& arg)
93 {
94         if(arg == NULL)
95                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
96
97         if(!JSValueIsObject(m_context, arg))
98                 return FilterPtr(NULL);
99                 //ThrowMsg(InvalidArgumentException, "Filter is not object.");
100
101         if(JSCompositeFilter::isObjectOfClass(m_context, arg))
102                 return DPL::StaticPointerCast<IFilter>(JSCompositeFilter::getCompositeFilter(m_context, arg));
103
104         if(JSAttributeFilter::isObjectOfClass(m_context, arg))
105                 return DPL::StaticPointerCast<IFilter>(JSAttributeFilter::getAttributeFilter(m_context, arg));
106
107         if(JSAttributeRangeFilter::isObjectOfClass(m_context, arg))
108                 return DPL::StaticPointerCast<IFilter>(JSAttributeRangeFilter::getAttributeRangeFilter(m_context, arg));
109
110         //ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Wrong attribute");
111         return FilterPtr(NULL);
112 }
113
114 JSValueRef FilterConverter::toJSValueRef(const FilterArrayPtr& arg)
115 {
116         if(arg == NULL)
117                 ThrowMsg(NullPointerException, "FilterArray is NULL.");
118
119         int size = arg->size();
120
121         JSObjectRef resultObject = JSCreateArrayObject(m_context, 0, NULL);
122         if (!resultObject)
123                 ThrowMsg(ConversionException, "Can not create array object.");
124
125         for(int i = 0; i < size; i++)
126         {
127                 JSValueRef jsvalue = toJSValueRef(arg->at(i));
128                 if(jsvalue == NULL)
129                         continue;
130
131                 if (!JSSetArrayElement(m_context, resultObject, i, jsvalue))
132                         ThrowMsg(ConversionException, "Can not fill Filter array.");
133         }
134
135         return static_cast<JSValueRef>(resultObject);
136 }
137
138 FilterArrayPtr FilterConverter::toFilterArray(const JSValueRef& arg)
139 {
140         if(arg == NULL)
141                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
142
143         if(!JSIsArrayValue(m_context, arg))
144                 ThrowMsg(InvalidArgumentException, "JSValueRef is not Array.");
145
146         FilterArrayPtr retVal;
147
148         JSObjectRef obj = toJSObjectRef(arg);
149         retVal = FilterArrayPtr(new FilterArray());
150
151         unsigned int length = JSGetArrayLength(m_context, obj);
152         for(unsigned int i=0; i<length; i++)
153         {
154                 JSValueRef value = JSGetArrayElement(m_context, obj, i);
155                 if(value == NULL)
156                 {
157                         LogWarning("value is NULL (" << i << ")");
158                         continue;
159                 }
160
161                 FilterPtr filter(NULL);
162                 filter = toFilter(value);
163                 if(filter == NULL)
164                 {
165                         LogWarning("Element is not an AbstractFilter (" << i << ")");
166                         continue;
167                 }
168
169                 retVal->push_back(filter);
170         }
171
172         return retVal;
173 }
174
175 JSValueRef FilterConverter::toJSValueRef(const CompositeFilterPtr& arg)
176 {
177         if(arg == NULL)
178                 ThrowMsg(NullPointerException, "CompositeFilter is NULL.");
179
180         const ScopedJSStringRef jsStrFilters(JSStringCreateWithUTF8CString(TIZEN_FILTER_CONVERTER_ATTRIBUTE_FILTERS));
181         JSValueRef jsValueFilters =     toJSValueRef(arg->getFilters());
182
183         JSObjectRef jsValueResult = WrtDeviceApis::CommonsJavaScript::JSUtils::makeObject(m_context, JSCompositeFilter::getClassRef(), arg);
184
185         JSObjectSetProperty(m_context, jsValueResult, jsStrFilters.get(), jsValueFilters, kJSPropertyAttributeNone, NULL);
186
187         return jsValueResult;
188 }
189
190 CompositeFilterPtr FilterConverter::toCompositeFilter(const JSValueRef& arg)
191 {
192         if(arg == NULL)
193                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
194
195         if(!JSCompositeFilter::isObjectOfClass(m_context, arg))
196                 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Wrong attribute");
197
198         CompositeFilterPtr compositeFilter = JSCompositeFilter::getCompositeFilter(m_context, arg);
199
200         FilterArrayPtr filters = FilterArrayPtr(new FilterArray());
201
202         const ScopedJSStringRef jsStrFilters(JSStringCreateWithUTF8CString(TIZEN_FILTER_CONVERTER_ATTRIBUTE_FILTERS));
203         JSObjectRef argObj = JSValueToObject(m_context, arg, NULL);
204         JSValueRef jsValueFilters = JSObjectGetProperty(m_context, argObj, jsStrFilters.get(), NULL);
205         filters = toFilterArray(jsValueFilters);
206         compositeFilter->setFilters(filters);
207
208         return compositeFilter;
209 }
210
211 JSValueRef FilterConverter::toJSValueRef(const AttributeFilterPtr& arg)
212 {
213         if(arg == NULL)
214                 ThrowMsg(NullPointerException, "AttributeFilter is NULL.");
215
216         return WrtDeviceApis::CommonsJavaScript::JSUtils::makeObject(m_context, JSAttributeFilter::getClassRef(), arg);
217 }
218
219 AttributeFilterPtr FilterConverter::toAttributeFilter(const JSValueRef& arg)
220 {
221         if(arg == NULL)
222                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
223
224         if(!JSAttributeFilter::isObjectOfClass(m_context, arg))
225                 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Wrong attribute");
226
227         return JSAttributeFilter::getAttributeFilter(m_context, arg);
228 }
229
230 JSValueRef FilterConverter::toJSValueRef(const AttributeRangeFilterPtr& arg)
231 {
232         if(arg == NULL)
233                 ThrowMsg(NullPointerException, "AttributeRangeFilter is NULL.");
234
235         return WrtDeviceApis::CommonsJavaScript::JSUtils::makeObject(m_context, JSAttributeRangeFilter::getClassRef(), arg);
236 }
237
238 AttributeRangeFilterPtr FilterConverter::toAttributeRangeFilter(const JSValueRef& arg)
239 {
240         if(arg == NULL)
241                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
242
243         if(!JSAttributeRangeFilter::isObjectOfClass(m_context, arg))
244                 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Wrong attribute");
245
246         return JSAttributeRangeFilter::getAttributeRangeFilter(m_context, arg);
247 }
248
249 JSValueRef FilterConverter::toJSValueRef(const SortModePtr& arg)
250 {
251         if(arg == NULL)
252                 ThrowMsg(NullPointerException, "SortMode is NULL.");
253
254         return WrtDeviceApis::CommonsJavaScript::JSUtils::makeObject(m_context, JSSortMode::getClassRef(), arg);
255 }
256
257 SortModePtr FilterConverter::toSortMode(const JSValueRef& arg)
258 {
259         if(arg == NULL)
260                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
261
262         if(!JSSortMode::isObjectOfClass(m_context, arg))
263                 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Wrong attribute");
264
265         return JSSortMode::getSortMode(m_context, arg);
266 }
267
268 JSValueRef FilterConverter::toJSValueRef(const SortModeArrayPtr& arg)
269 {
270         // Not used any more.
271         if(arg == NULL)
272                 ThrowMsg(NullPointerException, "SortModeArray is NULL.");
273
274         int size = arg->size();
275
276         JSObjectRef resultObject = JSCreateArrayObject(m_context, 0, NULL);
277         if (!resultObject)
278                 ThrowMsg(ConversionException, "Can not create array object.");
279
280         for(int i = 0; i < size; i++)
281         {
282                 JSValueRef jsvalue = toJSValueRef(arg->at(i));
283                 if (!JSSetArrayElement(m_context, resultObject, i, jsvalue))
284                         ThrowMsg(ConversionException, "Can not fill SortMode array.");
285         }
286
287         return static_cast<JSValueRef>(resultObject);
288 }
289
290 SortModeArrayPtr FilterConverter::toSortModeArray(const JSValueRef& arg)
291 {
292         // Not used any more.
293         if(arg == NULL)
294                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
295
296         if(!JSIsArrayValue(m_context, arg))
297                 ThrowMsg(InvalidArgumentException, "Not an array type.");
298
299         SortModeArrayPtr sortModeArray = SortModeArrayPtr(new SortModeArray());
300         JSObjectRef object = toJSObjectRef(arg);
301
302         unsigned int length = JSGetArrayLength(m_context, object);
303         for(unsigned int i=0; i<length; i++)
304         {
305                 JSValueRef value = JSGetArrayElement(m_context, object, i);
306
307                 if(JSValueIsNull(m_context, value) ||  JSValueIsUndefined(m_context, value)) {
308                         ThrowMsg(InvalidArgumentException, "CompositeFilter.filters has null elements.");
309                 }
310
311                 SortModePtr sortMode = toSortMode(value);
312
313                 sortModeArray->push_back(sortMode);
314         }
315
316         return sortModeArray;
317 }
318
319 JSValueRef FilterConverter::toJSValueRef(const AnyPtr& arg)
320 {
321         if(arg == NULL)
322                 ThrowMsg(NullPointerException, "Any is NULL.");
323
324         AnyTypeConverterFactory::ConverterType converter =
325                         AnyTypeConverterFactory::getConverter(m_context);
326
327         return converter->toJSValueRef(arg);
328 }
329
330 AnyPtr FilterConverter::toAny(const JSValueRef& arg)
331 {
332         if(arg == NULL)
333                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
334
335         AnyArrayPtr retVal;
336
337         AnyTypeConverterFactory::ConverterType converter =
338                         AnyTypeConverterFactory::getConverter(m_context);
339
340         return converter->toAny(arg);
341 }
342
343 JSValueRef FilterConverter::toJSValueRef(const AnyArrayPtr& arg)
344 {
345         if(arg == NULL)
346                 ThrowMsg(NullPointerException, "AnyArray is NULL.");
347
348         AnyTypeConverterFactory::ConverterType converter =
349                         AnyTypeConverterFactory::getConverter(m_context);
350
351         int size = arg->size();
352
353         JSObjectRef resultObject = JSCreateArrayObject(m_context, 0, NULL);
354         if (!resultObject)
355                 ThrowMsg(ConversionException, "Can not create array object.");
356
357         for(int i = 0; i < size; i++)
358         {
359                 JSValueRef jsvalue = converter->toJSValueRef(arg->at(i));
360                 if (!JSSetArrayElement(m_context, resultObject, i, jsvalue))
361                         ThrowMsg(ConversionException, "Can not fill any array.");
362         }
363
364         return static_cast<JSValueRef>(resultObject);
365 }
366
367 AnyArrayPtr FilterConverter::toAnyArray(const JSValueRef& arg)
368 {
369         if(arg == NULL)
370                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
371
372         AnyArrayPtr retVal;
373
374         retVal = AnyArrayPtr(new AnyArray());
375
376         JSObjectRef obj = toJSObjectRef(arg);
377         AnyTypeConverterFactory::ConverterType converter =
378                         AnyTypeConverterFactory::getConverter(m_context);
379
380         unsigned int length = JSGetArrayLength(m_context, obj);
381         for(unsigned int i=0; i<length; i++)
382         {
383                 JSValueRef value = JSGetArrayElement(m_context, obj, i);
384
385                 if(JSValueIsNull(m_context, value) ||  JSValueIsUndefined(m_context, value)) {
386                         ThrowMsg(InvalidArgumentException, "IDFilter.ids has null elements.");
387                 }
388                 AnyPtr any = converter->toAny(value);
389
390                 retVal->push_back(any);
391         }
392
393         return retVal;
394 }
395
396 JSValueRef FilterConverter::toJSValueRef(const FilterType& arg)
397 {
398         string compositeFilterTypeStr;
399
400         if(arg == UNION_FILTER)
401                 compositeFilterTypeStr = "UNION";
402         else if(arg == INTERSECTION_FILTER)
403                 compositeFilterTypeStr = "INTERSECTION";
404         else
405                 ThrowMsg(ConversionException, "Can not create CompositeFilterType.");
406
407         return toJSValueRef(compositeFilterTypeStr);
408 }
409
410 FilterType FilterConverter::toCompositeFilterType(const JSValueRef& arg)
411 {
412         if(arg == NULL)
413                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
414
415         if(!JSValueIsString(m_context, arg))
416                 ThrowMsg(InvalidArgumentException, "Value is not an string.");
417
418         string compositeFilterTypeStr = toString(arg);
419         FilterType compositeFilterType;
420
421         if(compositeFilterTypeStr == "UNION")
422                 compositeFilterType = UNION_FILTER;
423         else if(compositeFilterTypeStr == "INTERSECTION")
424                 compositeFilterType = INTERSECTION_FILTER;
425         else
426                 ThrowMsg(InvalidArgumentException, "CompositeFilterType cannot have " << compositeFilterTypeStr);
427
428         return compositeFilterType;
429 }
430
431 JSValueRef FilterConverter::toJSValueRef(const MatchFlag& arg)
432 {
433         string matchFlagStr;
434
435         if(arg == MATCH_EXACTLY)
436                 matchFlagStr = "EXACTLY";
437         else if(arg == MATCH_FULLSTRING)
438                 matchFlagStr = "FULLSTRING";
439         else if(arg == MATCH_CONTAINS)
440                 matchFlagStr = "CONTAINS";
441         else if(arg == MATCH_STARTSWITH)
442                 matchFlagStr = "STARTSWITH";
443         else if(arg == MATCH_ENDSWITH)
444                 matchFlagStr = "ENDSWITH";
445         else if(arg == MATCH_EXISTS)
446                 matchFlagStr = "EXISTS";
447         else
448                 ThrowMsg(ConversionException, "Can not create MatchFlag.");
449
450         return toJSValueRef(matchFlagStr);
451 }
452
453 MatchFlag FilterConverter::toMatchFlag(const JSValueRef& arg)
454 {
455         if(arg == NULL)
456                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
457
458         if(!JSValueIsString(m_context, arg))
459                 ThrowMsg(InvalidArgumentException, "Value is not an string.");
460
461         string matchFlagStr = toString(arg);
462         MatchFlag matchFlag;
463
464         if(matchFlagStr == "EXACTLY")
465                 matchFlag = MATCH_EXACTLY;
466         else if(matchFlagStr == "FULLSTRING")
467                 matchFlag = MATCH_FULLSTRING;
468         else if(matchFlagStr == "CONTAINS")
469                 matchFlag = MATCH_CONTAINS;
470         else if(matchFlagStr == "STARTSWITH")
471                 matchFlag = MATCH_STARTSWITH;
472         else if(matchFlagStr == "ENDSWITH")
473                 matchFlag = MATCH_ENDSWITH;
474         else if(matchFlagStr == "EXISTS")
475                 matchFlag = MATCH_EXISTS;
476         else
477                 ThrowMsg(InvalidArgumentException, "FilterMatchFlag cannot have " << matchFlagStr);
478
479         return matchFlag;
480 }
481
482 JSValueRef FilterConverter::toJSValueRef(const SortOrder& arg)
483 {
484         string sortOrderStr;
485
486         if(arg == ASCENDING_SORT_ORDER)
487                 sortOrderStr = "ASC";
488         else if(arg == DESCENDING_SORT_ORDER)
489                 sortOrderStr = "DESC";
490         else
491                 ThrowMsg(ConversionException, "Can not create SortModeOrder.");
492
493         return toJSValueRef(sortOrderStr);
494 }
495
496 SortOrder FilterConverter::toSortOrder(const JSValueRef& arg)
497 {
498         if(arg == NULL)
499                 ThrowMsg(NullPointerException, "JSValueRef is NULL.");
500
501         if(!JSValueIsString(m_context, arg))
502                 ThrowMsg(InvalidArgumentException, "Value is not an string.");
503
504         string sortOrderStr = toString(arg);
505         SortOrder sortOrder;
506
507         if(sortOrderStr == "ASC")
508                 sortOrder = ASCENDING_SORT_ORDER;
509         else if(sortOrderStr == "DESC")
510                 sortOrder = DESCENDING_SORT_ORDER;
511         else
512                 ThrowMsg(InvalidArgumentException, "SortModeOrder cannot have " << sortOrderStr);
513
514         return sortOrder;
515 }
516
517 void FilterConverter::initFilterAttrs()
518 {
519         m_compositeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_TYPE);
520         m_compositeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_FILTERS);
521
522         m_attributeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_ATTRIBUTE_NAME);
523         m_attributeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_MATCH_FLAG);
524         m_attributeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_MATCH_VALUES);
525
526         m_attributeRangeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_ATTRIBUTE_NAME);
527         m_attributeRangeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_INITIAL_VALUE);
528         m_attributeRangeFilterAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_END_VALUE);
529
530         m_sortModeAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_ORDER);
531         m_sortModeAttrs.push_back(TIZEN_FILTER_CONVERTER_ATTRIBUTE_ATTRIBUTE_NAME);
532 }
533
534 } // Tizen
535 } // DeviceAPI
536