2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
31 using namespace common;
33 AbstractFilter::AbstractFilter(FilterType filter_type) : m_filter_type(filter_type) {
37 AbstractFilter::~AbstractFilter() {
41 FilterType AbstractFilter::getFilterType() const {
45 bool AbstractFilter::isMatching(const FilterableObject* const tested_object) const {
46 LoggerE("Calling isMatching on AbstractFilter!");
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);
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) {
63 if (match_value.empty() && value.empty()) {
68 case AttributeMatchFlag::kEndsWith: {
69 if (match_value.empty()) {
72 if (match_value.size() > value.size()) {
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()) ==
81 case AttributeMatchFlag::kExactly: {
82 return match_value == value;
85 case AttributeMatchFlag::kStartsWith: {
86 if (match_value.empty()) {
89 if (match_value.size() > value.size()) {
92 std::string lvalue = convertToLowerCase(value);
93 std::string lmatch_value = convertToLowerCase(match_value);
94 return lvalue.substr(0, lmatch_value.size()) == lmatch_value;
97 case AttributeMatchFlag::kContains: {
98 if (match_value.empty()) {
101 if (match_value.size() > value.size()) {
104 std::string lvalue = convertToLowerCase(value);
105 std::string lmatch_value = convertToLowerCase(match_value);
106 return lvalue.find(lmatch_value) != std::string::npos;
109 case AttributeMatchFlag::kFullString: {
110 return convertToLowerCase(match_value) == convertToLowerCase(value);
114 LoggerE("Unknown match flag");
122 bool FilterUtils::isMatching(const Any& match_value, const std::string& value,
123 AttributeMatchFlag flag) {
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);
131 LoggerD("The type of match_value passed to the filter does not match the type of the attribute");
137 bool isANumberAndConvertibleToULong(const picojson::value& value) {
140 if (!value.is<double>()) {
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;
149 auto is_integer = std::ceil(number) == number;
151 return in_ul_range && is_integer;
156 bool FilterUtils::isMatching(const Any& match_value, const unsigned long value,
157 AttributeMatchFlag flag) {
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;
165 LoggerD("The type of match_value passed to the filter does not match the type of the attribute");
169 bool FilterUtils::isMatching(const Any& match_value, const bool value, AttributeMatchFlag flag) {
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;
177 LoggerD("The type of matchValue passed to the filter does not match the type of the attribute");
181 bool FilterUtils::isAnyStringMatching(const std::string& key,
182 const std::vector<std::string>& values,
183 AttributeMatchFlag flag) {
185 for (auto it = values.begin(); it != values.end(); ++it) {
186 if (isMatchingString(key, *it, flag)) {
193 bool FilterUtils::isTimeStampInRange(const time_t& time_stamp, tizen::AnyPtr& initial_value,
194 tizen::AnyPtr& end_value) {
197 if (!initial_value || !end_value) {
198 LoggerD("initial_value is %snull. end_value is %snull", initial_value ? "NOT " : "",
199 end_value ? "NOT " : "");
203 time_t from_time = initial_value->isNullOrUndefined() ? std::numeric_limits<time_t>::min()
204 : initial_value->toTimeT();
207 end_value->isNullOrUndefined() ? std::numeric_limits<time_t>::max() : end_value->toTimeT();
209 bool is_in_range = FilterUtils::isBetweenTimeRange(time_stamp, from_time, to_time);
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));