[Code format] Fixed formating with auto-format tool
[platform/core/api/webapi-plugins.git] / src / messaging / MsgCommon / AbstractFilter.cpp
1 /*
2  * Copyright (c) 2015 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 #include "AbstractFilter.h"
18 //#include "JSAttributeFilter.h"
19 //#include "JSAttributeRangeFilter.h"
20 //#include "JSCompositeFilter.h"
21 #include "common/logger.h"
22 #include "common/platform_exception.h"
23 #include "common/tools.h"
24 //#include <JSUtil.h>
25 #include <algorithm>
26 #include <limits>
27
28 namespace extension {
29 namespace tizen {
30
31 using namespace common;
32
33 AbstractFilter::AbstractFilter(FilterType filter_type) : m_filter_type(filter_type) {
34   ScopeLogger();
35 }
36
37 AbstractFilter::~AbstractFilter() {
38   ScopeLogger();
39 }
40
41 FilterType AbstractFilter::getFilterType() const {
42   return m_filter_type;
43 }
44
45 bool AbstractFilter::isMatching(const FilterableObject* const tested_object) const {
46   LoggerE("Calling isMatching on AbstractFilter!");
47   return false;
48 }
49
50 namespace {
51
52 std::string convertToLowerCase(const std::string& input_string) {
53   std::string output_string = input_string;
54   std::transform(output_string.begin(), output_string.end(), output_string.begin(), ::tolower);
55   return output_string;
56 }
57
58 // This function assumes, that the flag is not "EXISTS"
59 bool isMatchingString(const std::string& match_value, const std::string& value,
60                       AttributeMatchFlag flag) {
61   ScopeLogger();
62
63   if (match_value.empty() && value.empty()) {
64     return true;
65   }
66
67   switch (flag) {
68     case AttributeMatchFlag::kEndsWith: {
69       if (match_value.empty()) {
70         return false;
71       }
72       if (match_value.size() > value.size()) {
73         return false;
74       }
75       std::string lvalue = convertToLowerCase(value);
76       std::string lmatch_value = convertToLowerCase(match_value);
77       return lvalue.substr(lvalue.size() - lmatch_value.size(), lmatch_value.size()) ==
78              lmatch_value;
79     }
80
81     case AttributeMatchFlag::kExactly: {
82       return match_value == value;
83     }
84
85     case AttributeMatchFlag::kStartsWith: {
86       if (match_value.empty()) {
87         return false;
88       }
89       if (match_value.size() > value.size()) {
90         return false;
91       }
92       std::string lvalue = convertToLowerCase(value);
93       std::string lmatch_value = convertToLowerCase(match_value);
94       return lvalue.substr(0, lmatch_value.size()) == lmatch_value;
95     }
96
97     case AttributeMatchFlag::kContains: {
98       if (match_value.empty()) {
99         return false;
100       }
101       if (match_value.size() > value.size()) {
102         return false;
103       }
104       std::string lvalue = convertToLowerCase(value);
105       std::string lmatch_value = convertToLowerCase(match_value);
106       return lvalue.find(lmatch_value) != std::string::npos;
107     }
108
109     case AttributeMatchFlag::kFullString: {
110       return convertToLowerCase(match_value) == convertToLowerCase(value);
111     }
112
113     default: {
114       LoggerE("Unknown match flag");
115       return false;
116     }
117   }
118 }
119
120 };  // namespace
121
122 bool FilterUtils::isMatching(const Any& match_value, const std::string& value,
123                              AttributeMatchFlag flag) {
124   ScopeLogger();
125
126   const auto match_value_json = match_value.getValue();
127   if (match_value_json.is<std::string>()) {
128     return isMatchingString(match_value_json.get<std::string>(), value, flag);
129   }
130
131   LoggerD("The type of match_value passed to the filter does not match the type of the attribute");
132   return false;
133 }
134
135 namespace {
136
137 bool isANumberAndConvertibleToULong(const picojson::value& value) {
138   ScopeLogger();
139
140   if (!value.is<double>()) {
141     return false;
142   }
143
144   auto number = value.get<double>();
145   auto minimum = static_cast<double>(std::numeric_limits<unsigned long>::min());
146   auto maximum = static_cast<double>(std::numeric_limits<unsigned long>::max());
147   auto in_ul_range = minimum <= number && number <= maximum;
148
149   auto is_integer = std::ceil(number) == number;
150
151   return in_ul_range && is_integer;
152 }
153
154 };  // namespace
155
156 bool FilterUtils::isMatching(const Any& match_value, const unsigned long value,
157                              AttributeMatchFlag flag) {
158   ScopeLogger();
159
160   const auto match_value_json = match_value.getValue();
161   if (flag == AttributeMatchFlag::kExactly && isANumberAndConvertibleToULong(match_value_json)) {
162     return static_cast<unsigned long>(match_value_json.get<double>()) == value;
163   }
164
165   LoggerD("The type of match_value passed to the filter does not match the type of the attribute");
166   return false;
167 }
168
169 bool FilterUtils::isMatching(const Any& match_value, const bool value, AttributeMatchFlag flag) {
170   ScopeLogger();
171
172   const auto match_value_json = match_value.getValue();
173   if (match_value_json.is<bool>() && AttributeMatchFlag::kExactly == flag) {
174     return match_value_json.get<bool>() == value;
175   }
176
177   LoggerD("The type of matchValue passed to the filter does not match the type of the attribute");
178   return false;
179 }
180
181 bool FilterUtils::isAnyStringMatching(const std::string& key,
182                                       const std::vector<std::string>& values,
183                                       AttributeMatchFlag flag) {
184   ScopeLogger();
185   for (auto it = values.begin(); it != values.end(); ++it) {
186     if (isMatchingString(key, *it, flag)) {
187       return true;
188     }
189   }
190   return false;
191 }
192
193 bool FilterUtils::isTimeStampInRange(const time_t& time_stamp, tizen::AnyPtr& initial_value,
194                                      tizen::AnyPtr& end_value) {
195   ScopeLogger();
196
197   if (!initial_value || !end_value) {
198     LoggerD("initial_value is %snull. end_value is %snull", initial_value ? "NOT " : "",
199             end_value ? "NOT " : "");
200     return false;
201   }
202
203   time_t from_time = initial_value->isNullOrUndefined() ? std::numeric_limits<time_t>::min()
204                                                         : initial_value->toTimeT();
205
206   time_t to_time =
207       end_value->isNullOrUndefined() ? std::numeric_limits<time_t>::max() : end_value->toTimeT();
208
209   bool is_in_range = FilterUtils::isBetweenTimeRange(time_stamp, from_time, to_time);
210
211   LoggerD("%lld is%s in time range <%lld, %lld>", static_cast<long long>(time_stamp),
212           (is_in_range ? "" : " NOT"), static_cast<long long>(from_time),
213           static_cast<long long>(to_time));
214
215   return is_in_range;
216 }
217
218 }  // Tizen
219 }  // DeviceAPI