tizen 2.3.1 release
[framework/web/wearable/wrt-plugins-tizen.git] / src / Tizen / AbstractFilter.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012-2013 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 "AbstractFilter.h"
19 #include "JSAttributeFilter.h"
20 #include "JSAttributeRangeFilter.h"
21 #include "JSCompositeFilter.h"
22 #include <PlatformException.h>
23 #include <Logger.h>
24 #include <JSUtil.h>
25 #include <algorithm>
26
27 namespace DeviceAPI {
28 namespace Tizen {
29
30 using namespace Common;
31
32 AbstractFilter::AbstractFilter(FilterType filter_type) :
33         m_filter_type(filter_type)
34 {
35 }
36
37 AbstractFilter::~AbstractFilter()
38 {
39 }
40
41 FilterType AbstractFilter::getFilterType() const
42 {
43     return m_filter_type;
44 }
45
46 JSValueRef AbstractFilter::makeJSValue(JSContextRef context,
47         AbstractFilterPtr native)
48 {
49     LOGD("Entered");
50
51     if (!native) {
52         LOGE("Native is null");
53         throw UnknownException("Native is null");
54     }
55
56     switch (native->getFilterType()) {
57         case ATTRIBUTE_FILTER:
58             return JSAttributeFilter::makeJSObject(context, native);
59         case ATTRIBUTE_RANGE_FILTER:
60             return JSAttributeRangeFilter::makeJSObject(context, native);
61         case COMPOSITE_FILTER:
62             return JSCompositeFilter::makeJSObject(context, native);
63         default:
64             LOGE("Unsupported filter type");
65             throw UnknownException("Unsupported filter type");
66     }
67 }
68
69 AbstractFilterPtr AbstractFilter::getPrivateObject(JSContextRef context,
70         JSValueRef value)
71 {
72     JSObjectRef object = JSUtil::JSValueToObject(context, value);
73
74     if (!JSValueIsObjectOfClass(context, value, JSAttributeFilter::getClassRef()) &&
75         !JSValueIsObjectOfClass(context, value, JSAttributeRangeFilter::getClassRef()) &&
76         !JSValueIsObjectOfClass(context, value, JSCompositeFilter::getClassRef())) {
77         LOGE("JSObjectRef:%p - Object type is not JSAttributeFilter, "
78                 "JSAttributeRangeFilter nor JSCompositeFilter", object);
79         throw TypeMismatchException("Object type is not valid filter");
80     }
81
82     AbstractFilterHolder* priv =
83             static_cast<AbstractFilterHolder*>(JSObjectGetPrivate(object));
84     if (!priv) {
85         LOGE("Holder is null");
86         throw UnknownException("Holder is null");
87     }
88     if (!(priv->ptr)) {
89         LOGE("Priv is null");
90         throw UnknownException("Priv is null");
91     }
92     return priv->ptr;
93 }
94
95
96 bool AbstractFilter::isMatching(const FilterableObject* const tested_object) const
97 {
98     LOGE("Calling isMatching on AbstractFilter!");
99     throw UnknownException("Method not supported");
100 }
101
102 AttributeFilterPtr castToAttributeFilter(AbstractFilterPtr from)
103 {
104     if(ATTRIBUTE_FILTER != from->getFilterType()) {
105         LOGE("Trying to get AttributeFilterPtr but filter's type is: %d",
106                 from->getFilterType());
107         return AttributeFilterPtr();
108     }
109
110     return std::dynamic_pointer_cast<AttributeFilter>(from);
111 }
112
113 AttributeRangeFilterPtr castToAttributeRangeFilter(AbstractFilterPtr from)
114 {
115     if(ATTRIBUTE_RANGE_FILTER != from->getFilterType()) {
116         LOGE("Trying to get AttributeRangeFilterPtr but filter's type is: %d",
117                 from->getFilterType());
118         return AttributeRangeFilterPtr();
119     }
120
121     return std::dynamic_pointer_cast<AttributeRangeFilter>(from);
122 }
123
124 CompositeFilterPtr castToCompositeFilter(AbstractFilterPtr from)
125 {
126     if(COMPOSITE_FILTER != from->getFilterType()) {
127         LOGE("Trying to get CompositeFilterPtr but filter's type is: %d",
128                 from->getFilterType());
129         return CompositeFilterPtr();
130     }
131
132     return std::dynamic_pointer_cast<CompositeFilter>(from);
133 }
134
135 namespace {
136
137 inline std::string convertToLowerCase(const std::string& input_string)
138 {
139     std::string output_string = input_string;
140     std::transform(output_string.begin(), output_string.end(), output_string.begin(),
141             ::tolower);
142     return output_string;
143 }
144
145 } // Anonymous namespace
146
147 bool FilterUtils::isStringMatching(const std::string& key,
148         const std::string& value,
149         Tizen::FilterMatchFlag flag)
150 {
151     switch(flag)
152     {
153         case Tizen::ENDSWITH: {
154             if (key.empty()) {
155                 return false;
156             }
157             if (key.size() > value.size()) {
158                 return false;
159             }
160             std::string lvalue = convertToLowerCase(value);
161             std::string lkey = convertToLowerCase(key);
162             return lvalue.substr(lvalue.size() - lkey.size(), lkey.size()) == lkey;
163         }
164
165         case Tizen::EXACTLY: {
166             return key == value;
167         }
168
169         case Tizen::STARTSWITH: {
170             if (key.empty()) {
171                 return false;
172             }
173             if (key.size() > value.size()) {
174                 return false;
175             }
176             std::string lvalue = convertToLowerCase(value);
177             std::string lkey = convertToLowerCase(key);
178             return lvalue.substr(0, lkey.size()) == lkey;
179         }
180
181         case Tizen::CONTAINS: {
182             if (key.empty()) {
183                 return false;
184             }
185             if (key.size() > value.size()) {
186                 return false;
187             }
188             std::string lvalue = convertToLowerCase(value);
189             std::string lkey = convertToLowerCase(key);
190             return lvalue.find(lkey) != std::string::npos;
191         }
192
193         default: {
194             LOGE("Unknown match flag");
195             return false;
196         }
197     }
198 }
199
200 bool FilterUtils::isAnyStringMatching(const std::string& key,
201         const std::vector<std::string>& values,
202         Tizen::FilterMatchFlag flag)
203 {
204     for(auto it = values.begin(); it != values.end(); ++it) {
205         if(isStringMatching(key,*it,flag)) {
206             return true;
207         }
208     }
209     return false;
210 }
211
212 bool FilterUtils::isTimeStampInRange(const time_t& time_stamp,
213         Tizen::AnyPtr& initial_value,
214         Tizen::AnyPtr& end_value)
215 {
216     time_t from_time = 0;
217     time_t to_time = 0;
218
219     bool initial_is_valid_time_value = false;
220     if (initial_value && !initial_value->isNullOrUndefined()) {
221         try {
222             struct tm ftime = *initial_value->toDateTm();
223             from_time = mktime(&ftime);
224             initial_is_valid_time_value = true;
225         }
226         catch(...) {
227             LOGE("Unknown exception occured during execution of Any::toDateTm()");
228         }
229     }
230     if(!initial_is_valid_time_value) {
231         LOGE("initialValue is not Time!");
232         throw InvalidValuesException("initialValue is not Time!");
233     }
234
235     bool end_is_valid_time_value = false;
236     if (end_value && !end_value->isNullOrUndefined()) {
237         try {
238             struct tm ttime = *end_value->toDateTm();
239             to_time = mktime(&ttime);
240             end_is_valid_time_value = true;
241         }
242         catch(...) {
243             LOGE("Unknown exception occured during execution of Any::toDateTm()");
244         }
245     }
246     if(end_is_valid_time_value) {
247         LOGE("endValue is not Time!");
248         throw InvalidValuesException("endValue is not Time!");
249     }
250
251     bool is_in_range = FilterUtils::isBetweenTimeRange(time_stamp, from_time, to_time);
252
253     LOGD("%d is%s in time range <%d, %d>", time_stamp, (is_in_range ? "" : " NOT"),
254             from_time, to_time);
255
256     return is_in_range;
257 }
258
259 } //Tizen
260 } //DeviceAPI