Cleanup the build scripts and reorganize the source directories 14/137814/3
authorMu-Woong Lee <muwoong.lee@samsung.com>
Mon, 10 Jul 2017 02:04:42 +0000 (11:04 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Mon, 10 Jul 2017 02:13:30 +0000 (11:13 +0900)
Change-Id: I9121a3405d1497541afb929ff67e9c3185cfeb0c
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
29 files changed:
AUTHORS
CMakeLists.txt
packaging/capi-context.spec
src/ComparisonConverter.cpp [deleted file]
src/ComparisonConverter.h [deleted file]
src/IntComparisonConverter.cpp [deleted file]
src/IntComparisonConverter.h [deleted file]
src/StringComparisonConverter.cpp [deleted file]
src/StringComparisonConverter.h [deleted file]
src/TriggerOldRuleTypes.h [deleted file]
src/context_history.cpp [deleted file]
src/context_trigger.cpp [deleted file]
src/history/context_history.cpp [new file with mode: 0644]
src/rule_util.cpp [deleted file]
src/rule_util.h [deleted file]
src/rule_validator.cpp [deleted file]
src/rule_validator.h [deleted file]
src/trigger/ComparisonConverter.cpp [new file with mode: 0644]
src/trigger/ComparisonConverter.h [new file with mode: 0644]
src/trigger/IntComparisonConverter.cpp [new file with mode: 0644]
src/trigger/IntComparisonConverter.h [new file with mode: 0644]
src/trigger/StringComparisonConverter.cpp [new file with mode: 0644]
src/trigger/StringComparisonConverter.h [new file with mode: 0644]
src/trigger/TriggerOldRuleTypes.h [new file with mode: 0644]
src/trigger/context_trigger.cpp [new file with mode: 0644]
src/trigger/rule_util.cpp [new file with mode: 0644]
src/trigger/rule_util.h [new file with mode: 0644]
src/trigger/rule_validator.cpp [new file with mode: 0644]
src/trigger/rule_validator.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index 59ec358604c0a712dfc61fa526fec2c84a7de28f..15d0a895ed94b9ab6c5a361f62f3c6eba07490d8 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,2 @@
-Mu-Woong Lee    <muwoong.lee@samsung.com>
 Somin Kim       <somin926.kim@samsung.com>
+Mu-Woong Lee    <muwoong.lee@samsung.com>
index 430be884c27322b84cbf3a322f123cec88434f84..0a8d0609c7f75553158ef7609a56366e811a1eb8 100644 (file)
@@ -5,13 +5,15 @@ INCLUDE(GNUInstallDirs)
 # Targets
 SET(target ${PROJECT_NAME})
 
+# Dependencies
+SET(DEPS "gio-2.0 jsoncpp bundle pkgmgr-info capi-base-common capi-appfw-app-control")
+SET(DEPS "${DEPS} context-app-history-client context-job-scheduler-client")
+SET(DEPS "${DEPS} context-common-legacy")
+
 # Source Lists
 FILE(GLOB_RECURSE SRCS src/*.cpp)
 MESSAGE("Sources: ${SRCS}")
 
-# Dependencies
-SET(DEPS "gio-2.0 jsoncpp context-common-legacy aul bundle capi-appfw-app-control pkgmgr-info context-app-history-client")
-
 # Common Options
 INCLUDE(FindPkgConfig)
 INCLUDE_DIRECTORIES(
@@ -40,9 +42,9 @@ SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER})
 # Installing
 INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR})
 INSTALL(
-       DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/context-service
-       FILES_MATCHING
-       PATTERN "*.h"
+       DIRECTORY ${CMAKE_SOURCE_DIR}/include/
+       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/context-service
+       FILES_MATCHING PATTERN "*.h"
 )
 
 SET(VERSION ${FULLVER})
index 6eecaf9c5181198455b5da0e0ef9142ced8557b2..c1c47125a2b92acb8bda6fbd9586f160b4ca10eb 100644 (file)
@@ -1,19 +1,23 @@
 Name:       capi-context
 Summary:    Tizen Context Framework Native API
-Version:    1.0.2
+Version:    1.0.3
 Release:    1
-Group:      Service/Context
+Group:      Service Framework/Context
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 
 BuildRequires: cmake
 BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(jsoncpp)
-BuildRequires: pkgconfig(aul)
+#BuildRequires: pkgconfig(aul)
 BuildRequires: pkgconfig(bundle)
-BuildRequires: pkgconfig(capi-appfw-app-control)
 BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(capi-appfw-app-control)
 BuildRequires: pkgconfig(context-app-history-client)
+BuildRequires: pkgconfig(context-job-scheduler-client)
+
+# Legacy support
 BuildRequires: pkgconfig(context-common-legacy)
 Requires: context-agent
 
@@ -29,8 +33,8 @@ Tizen Context Framework Native API
 %build
 MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 
-export CXXFLAGS+=" -Wextra -Wcast-align -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-parameter"
-export CXXFLAGS+=" -Wno-empty-body -fomit-frame-pointer -fno-optimize-sibling-calls"
+export CXXFLAGS+=" -Wall -Wextra -Wcast-align -Wshadow -Wwrite-strings -Wswitch-default -Wno-unused-parameter"
+export CXXFLAGS+=" -Wformat=2 -Wno-empty-body -fomit-frame-pointer -fno-optimize-sibling-calls"
 export CXXFLAGS+=" -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow"
 export CXXFLAGS+=" -Wnon-virtual-dtor -std=c++0x"
 
@@ -70,7 +74,7 @@ Tizen Context Framework Native API (Development)
 
 %package test
 Summary:    Tizen Context Framework Testsuite
-Group:      Service/Context
+Group:      Service Framework/Context
 
 %description test
 Tizen Context Framework Testsuite
diff --git a/src/ComparisonConverter.cpp b/src/ComparisonConverter.cpp
deleted file mode 100644 (file)
index 3d73626..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "ComparisonConverter.h"
-
-using namespace ctx;
-
-ComparisonConverter::ComparisonConverter(const char* type, CtxJson1& info) :
-       __completed(false),
-       __size(0),
-       __logicalOp(TRIG_RULE_LOGICAL_DISJUNCTION),
-       __type(type),
-       __info(info.str()),
-       __result(EMPTY_JSON_OBJECT)
-{
-       __info.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &__key);
-       __info.get(NULL, OLD_TRIG_RULE_KEY_OPERATOR, &__logicalOp);
-       __size = __info.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
-}
-
-int ComparisonConverter::getResult(CtxJson1* result)
-{
-       if (__result == EMPTY_JSON_OBJECT)
-               return ERR_INVALID_RULE;
-
-       *result = __result.str();
-
-       return ERR_NONE;
-}
-
-void ComparisonConverter::__convertComparison()
-{
-       IF_FAIL_VOID(!__convertEmptyComparison());
-       IF_FAIL_VOID(!__convertSingleComparison());
-       IF_FAIL_VOID(!__convertMultipleComparison());
-
-       _E("Failed to convert comparison as new format");
-}
-
-bool ComparisonConverter::__convertEmptyComparison()
-{
-       IF_FAIL_RETURN(__size == 0, false);
-
-       CtxJson1 temp = EMPTY_JSON_OBJECT;
-       __result.set(NULL, __key.c_str(), temp);
-
-       return true;
-}
-
-bool ComparisonConverter::__convertSingleComparison()
-{
-       IF_FAIL_RETURN(__size == 1, false);
-
-       std::string op;
-       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, 0, &op);
-
-       __setConvertedOperator(op);
-       __setComparisonValue();
-
-       return true;
-}
-
-bool ComparisonConverter::__convertMultipleComparison()
-{
-       IF_FAIL_RETURN(__size > 1, false);
-
-       if (__checkOneOf()) {
-               return true;
-       } else if (__checkNoneOf()) {
-               return true;
-       } else if (__checkEtc()) {
-               return true;
-       }
-
-       return false;
-}
-
-bool ComparisonConverter::__checkOneOf()
-{
-       // Or of {==, ...}
-       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
-       IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_EQUAL_TO), false);
-
-       __setConvertedOperator(TRIG_RULE_OP_ONE_OF);
-       __setComparisonValueArray();
-
-       return true;
-}
-
-bool ComparisonConverter::__checkNoneOf()
-{
-       // And of {!=, ...}
-       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
-       IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_NOT_EQUAL_TO), false);
-
-       __setConvertedOperator(TRIG_RULE_OP_NONE_OF);
-       __setComparisonValueArray();
-
-       return true;
-}
-
-bool ComparisonConverter::__checkEtc()
-{
-       return false;
-}
-
-void ComparisonConverter::__setConvertedOperator(std::string op)
-{
-       __result.set(__key.c_str(), TRIG_RULE_KEY_OPERATOR, op);
-}
-
-void ComparisonConverter::__setComparisonValue()
-{
-       std::string valStr;
-       int val;
-
-       if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &valStr)) {
-               __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
-       } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &val)) {
-               __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
-       }
-}
-
-void ComparisonConverter::__setComparisonValueArray()
-{
-       std::string valStr;
-       int val;
-       // TODO sort
-       for (int i = 0; i < __size; i++) {
-               if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &valStr)) {
-                       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
-               } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val)) {
-                       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
-               }
-       }
-}
-
diff --git a/src/ComparisonConverter.h b/src/ComparisonConverter.h
deleted file mode 100644 (file)
index 9cde85c..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_COMPARISON_CONVERTER_H_
-#define _CONTEXT_COMPARISON_CONVERTER_H_
-
-#include <CtxJson1.h>
-#include "TriggerOldRuleTypes.h"
-
-namespace ctx {
-
-       class ComparisonConverter {
-       public:
-               virtual ~ComparisonConverter() {};
-
-               int getResult(CtxJson1* result);
-
-       protected:
-               bool __completed;
-               int __size;
-               std::string __logicalOp;
-               std::string __type;
-               CtxJson1 __info;
-               CtxJson1 __result;
-               std::string __key;
-
-               ComparisonConverter(const char* type, CtxJson1& info);
-               void __convertComparison();
-               virtual int __getOperatorCount(std::string op) = 0;
-               virtual bool __checkEtc();
-               void __setConvertedOperator(std::string op);
-
-       private:
-               bool __convertEmptyComparison();
-               bool __convertSingleComparison();
-               bool __convertMultipleComparison();
-               bool __checkOneOf();
-               bool __checkNoneOf();
-               void __setComparisonValue();
-               void __setComparisonValueArray();
-       };
-
-}      /* namespace ctx */
-
-#endif /* _CONTEXT_COMPARISON_CONVERTER_H_ */
diff --git a/src/IntComparisonConverter.cpp b/src/IntComparisonConverter.cpp
deleted file mode 100644 (file)
index 9f1a4e5..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <map>
-#include <list>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "IntComparisonConverter.h"
-
-using namespace ctx;
-
-IntComparisonConverter::IntComparisonConverter(CtxJson1 info) :
-       ComparisonConverter(TRIG_TMPL_TYPE_INTEGER, info)
-{
-       if (__size >= 2) {
-               for (int i = 0; i < __size; i++) {
-                       int val;
-                       std::string op;
-                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val);
-                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
-
-                       __insertComparisonInfo(op, val);
-               }
-               __sort();
-       }
-
-       __convertComparison();
-}
-
-void IntComparisonConverter::__insertComparisonInfo(std::string op, int val)
-{
-       IntComparisonMap::iterator it = __map.find(op);
-       if (it == __map.end()) {
-               IntList list;
-               list.push_back(val);
-               __map[op] = list;
-       } else {
-               it->second.push_back(val);
-       }
-}
-
-void IntComparisonConverter::__sort()
-{
-       for (IntComparisonMap::iterator it = __map.begin(); it != __map.end(); it++) {
-               it->second.sort();
-       }
-}
-
-int IntComparisonConverter::__getOperatorCount(std::string op)
-{
-       return __map[op].size();
-}
-
-int IntComparisonConverter::__getMaxValue(std::string op)
-{
-       return __map[op].back();
-}
-
-int IntComparisonConverter::__getMinValue(std::string op)
-{
-       return __map[op].front();
-}
-
-bool IntComparisonConverter::__checkEtc()
-{
-       // Simple version in, notIn
-       IF_FAIL_RETURN(!__checkIn(), true);
-       IF_FAIL_RETURN(!__checkNotIn(), true);
-
-       return false;
-}
-
-
-bool IntComparisonConverter::__checkIn()
-{
-       // And of { >= min, <= max }
-       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
-       IF_FAIL_RETURN(__size == 2, false);
-       IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO) == 1
-                       && __getOperatorCount(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) == 1, false);
-
-       int maxOfGE = __getMaxValue(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO);
-       int minOfLE = __getMinValue(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO);
-       IF_FAIL_RETURN(maxOfGE <= minOfLE, false);
-
-       __setConvertedOperator(TRIG_RULE_OP_IN);
-       __setComparisonValue(maxOfGE, minOfLE);
-
-       return true;
-}
-
-bool IntComparisonConverter::__checkNotIn()
-{
-       // Or of { < min, > max }
-       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
-       IF_FAIL_RETURN(__size == 2, false);
-       IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN) == 1
-                       && __getOperatorCount(TRIG_RULE_OP_LESS_THAN) == 1, false);
-
-       int maxOfL = __getMaxValue(TRIG_RULE_OP_LESS_THAN);
-       int minOfG = __getMinValue(TRIG_RULE_OP_GREATER_THAN);
-       IF_FAIL_RETURN(maxOfL <= minOfG, false);
-
-       __setConvertedOperator(TRIG_RULE_OP_NOT_IN);
-       __setComparisonValue(maxOfL, minOfG);
-
-       return true;
-}
-
-void IntComparisonConverter::__setComparisonValue(int val1, int val2)
-{
-       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val1);
-       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val2);
-}
-
diff --git a/src/IntComparisonConverter.h b/src/IntComparisonConverter.h
deleted file mode 100644 (file)
index f18cd2b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_INT_COMPARISON_CONVERTER_H_
-#define _CONTEXT_INT_COMPARISON_CONVERTER_H_
-
-#include <list>
-#include <CtxJson1.h>
-#include "ComparisonConverter.h"
-
-namespace ctx {
-
-       class IntComparisonConverter : public ComparisonConverter {
-               typedef std::list<int> IntList;         // Integer value list
-               typedef std::map<std::string, IntList> IntComparisonMap;                // { operator, IntList }
-
-       public:
-               IntComparisonConverter(CtxJson1 info);
-               ~IntComparisonConverter() {};
-
-       private:
-               IntComparisonMap __map;
-
-               void __insertComparisonInfo(std::string op, int val);
-               void __sort();
-               int __getMaxValue(std::string op);
-               int __getMinValue(std::string op);
-
-               bool __checkIn();
-               bool __checkNotIn();
-               void __setComparisonValue(int val1, int val2);
-               /* From CompariconConverter */
-               int __getOperatorCount(std::string op);
-               bool __checkEtc();
-       };
-
-}      /* namespace ctx */
-
-#endif /* _CONTEXT_INT_COMPARISON_CONVERTER_H_ */
diff --git a/src/StringComparisonConverter.cpp b/src/StringComparisonConverter.cpp
deleted file mode 100644 (file)
index f4c1757..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "StringComparisonConverter.h"
-
-using namespace ctx;
-
-StringComparisonConverter::StringComparisonConverter(CtxJson1 info) :
-       ComparisonConverter(TRIG_TMPL_TYPE_STRING, info)
-{
-       if (__size >= 2) {
-               for (int i = 0; i < __size; i++) {
-                       std::string op;
-                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
-
-                       __map[op]++;
-               }
-       }
-
-       __convertComparison();
-}
-
-
-int StringComparisonConverter::__getOperatorCount(std::string op)
-{
-       return __map[op];
-}
-
diff --git a/src/StringComparisonConverter.h b/src/StringComparisonConverter.h
deleted file mode 100644 (file)
index 69fb110..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_STRING_COMPARISON_CONVERTER_H_
-#define _CONTEXT_STRING_COMPARISON_CONVERTER_H_
-
-#include <map>
-#include <CtxJson1.h>
-#include "ComparisonConverter.h"
-
-namespace ctx {
-
-       class StringComparisonConverter : public ComparisonConverter {
-               typedef std::map<std::string, int> StringComparisonMap;
-
-       public:
-               StringComparisonConverter(CtxJson1 info);
-               ~StringComparisonConverter() {};
-
-       private:
-               StringComparisonMap __map;
-
-               /* From CompariconConverter */
-               int __getOperatorCount(std::string op);
-       };
-
-}      /* namespace ctx */
-
-#endif /* _CONTEXT_STRING_COMPARISON_CONVERTER_H_ */
diff --git a/src/TriggerOldRuleTypes.h b/src/TriggerOldRuleTypes.h
deleted file mode 100644 (file)
index fe85d67..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
-#define _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
-
-/* Old Rule Keys */
-#define OLD_TRIG_RULE_KEY_EVENT "EVENT"
-#define OLD_TRIG_RULE_KEY_EVENT_ITEM "ITEM_NAME"
-#define OLD_TRIG_RULE_KEY_EVENT_OPERATOR "ITEM_OPERATOR"
-#define OLD_TRIG_RULE_KEY_EVENT_OPTION "OPTION"
-#define OLD_TRIG_RULE_KEY_OPERATOR "OPERATOR"
-#define OLD_TRIG_RULE_KEY_CONDITION "CONDITION"
-#define OLD_TRIG_RULE_KEY_CONDITION_ITEM "ITEM_NAME"
-#define OLD_TRIG_RULE_KEY_CONDITION_OPERATOR "ITEM_OPERATOR"
-#define OLD_TRIG_RULE_KEY_CONDITION_OPTION "OPTION"
-#define OLD_TRIG_RULE_KEY_DATA_ARR "DATA_ARR"
-#define OLD_TRIG_RULE_KEY_DATA_KEY "DATA_KEY"
-#define OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR "DATA_KEY_OPERATOR"
-#define OLD_TRIG_RULE_KEY_DATA_VALUE_ARR "DATA_VALUE_ARR"
-#define OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR "DATA_VALUE_OPER_ARR"
-
-#endif /* _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_ */
diff --git a/src/context_history.cpp b/src/context_history.cpp
deleted file mode 100644 (file)
index 3770d2f..0000000
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <map>
-#include <json/json.h>
-#include <ContextTypes.h>
-#include <Tuple.h>
-#include <app_history_internal.h>
-#include <app_history_types_internal.h>
-#include <AppHistoryTypes.h>
-#include <context_history.h>
-
-#define HISTORY_DEPRECATED_DATA "DEPRECATION WARNING: This history data type is deprecated and will be removed from next release"
-#define HISTORY_DEPRECATED_FILTER "DEPRECATION WARNING: This history filter is deprecated and will be removed from next release"
-#define TYPE_NUMERIC 0
-#define TYPE_STRING 1
-#define FILTER_KEY_LIMIT 10
-
-#define ASSERT_ALLOC(X)                IF_FAIL_RETURN_TAG(X, E_NO_MEM, _E, "Memory allocation failed")
-#define ASSERT_NOT_NULL(X)     IF_FAIL_RETURN_TAG(X, E_PARAM, _E, "Parameter null")
-
-// handles
-typedef struct _context_history_handle_s {
-       /* At this point, this handle has no purpose.
-          But, it will be used to support other functionalities later,
-          e.g., async read or session management. */
-       int tmp;
-} _cx_history_handle;
-
-typedef struct _context_history_filter_handle_s {
-       Json::Value jfilter;
-} _cx_history_filter_handle;
-
-typedef struct _context_history_list_handle_s {
-       ctx_history_cursor_h cursor;
-
-       _context_history_list_handle_s() {
-               cursor = NULL;
-       }
-} _cx_history_list_handle;
-
-typedef struct _context_history_record_handle_s {
-       std::vector<std::string> keys;
-       std::shared_ptr<ctx::Tuple> tuple;
-} _cx_history_record_handle;
-
-static std::string convert_filter_to_string(context_history_filter_e filter_type);
-static std::string convert_data_to_string(context_history_data_e data_type);
-static bool check_record_key_data_type(int type, std::string key);
-static bool check_filter_data_int(context_history_filter_e filter_type, int val);
-static bool check_filter_data_string(context_history_filter_e filter_type, const char* val);
-static bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter);
-static int __getIndexOf(context_history_record_h record, const std::string& key);
-static bool history_is_deprecated(context_history_data_e data_type);
-static bool history_filter_is_deprecated(context_history_filter_e filter_type);
-
-// life-cycle
-EXPORT_API int context_history_create(context_history_h* handle)
-{
-       ASSERT_NOT_NULL(handle);
-
-       *handle = new(std::nothrow) _cx_history_handle();
-       ASSERT_ALLOC(*handle);
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_destroy(context_history_h handle)
-{
-       ASSERT_NOT_NULL(handle);
-       delete handle;
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-// Read filter manipulation
-EXPORT_API int context_history_filter_create(context_history_filter_h* filter)
-{
-       ASSERT_NOT_NULL(filter);
-
-       *filter = new(std::nothrow) _cx_history_filter_handle();
-       ASSERT_ALLOC(*filter);
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_filter_destroy(context_history_filter_h filter)
-{
-       ASSERT_NOT_NULL(filter);
-       delete filter;
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_filter_set_int(context_history_filter_h filter, context_history_filter_e filter_type, int val)
-{
-       ASSERT_NOT_NULL(filter);
-
-       if (history_filter_is_deprecated(filter_type)) {
-               _W(HISTORY_DEPRECATED_FILTER);
-       }
-
-       std::string filter_str = convert_filter_to_string(filter_type);
-       if (filter_str.empty()) {
-               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
-       }
-
-       // Check filter and its data type
-       IF_FAIL_RETURN_TAG(check_filter_data_int(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
-
-       filter->jfilter[filter_str] = val;
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_filter_set_string(context_history_filter_h filter, context_history_filter_e filter_type, const char* val)
-{
-       ASSERT_NOT_NULL(filter);
-       ASSERT_NOT_NULL(val);
-
-       _W("DEPRECATION WARNING: context_history_filter_set_string() is deprecated and will be removed from next release.");
-       if (history_filter_is_deprecated(filter_type)) {
-               _W(HISTORY_DEPRECATED_FILTER);
-       }
-
-       std::string filter_str = convert_filter_to_string(filter_type);
-       if (filter_str.empty()) {
-               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
-       }
-
-       // Check filter and its data type
-       IF_FAIL_RETURN_TAG(check_filter_data_string(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
-
-       filter->jfilter[filter_str] = val;
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_is_supported(context_history_data_e data_type, bool* supported)
-{
-       ASSERT_NOT_NULL(supported);
-
-       if (history_is_deprecated(data_type)) {
-               _W(HISTORY_DEPRECATED_DATA);
-       }
-
-       std::string data_type_str = convert_data_to_string(data_type);
-       if (data_type_str.empty()) {
-               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
-       }
-
-       return ctx_history_is_supported(data_type_str.c_str(), supported);
-}
-
-EXPORT_API int context_history_get_list(context_history_h handle, context_history_data_e data_type, context_history_filter_h filter, context_history_list_h* list)
-{
-       ASSERT_NOT_NULL(handle);
-       ASSERT_NOT_NULL(list);
-       *list = NULL;
-
-       if (history_is_deprecated(data_type)) {
-               _W(HISTORY_DEPRECATED_DATA);
-       }
-       /*TODO: Boundary check for filter values has to be done*/
-
-       std::string data_type_str = convert_data_to_string(data_type);
-       if (data_type_str.empty()) {
-               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
-       }
-
-       // Check data type & filter
-       if (filter)
-               IF_FAIL_RETURN_TAG(check_invalid_filter(data_type, filter), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid filter key");
-
-       *list = new(std::nothrow) _cx_history_list_handle();
-       ASSERT_ALLOC(*list);
-
-       std::string filterStr;
-       if (filter) {
-               Json::FastWriter fw;
-               fw.omitEndingLineFeed();
-               filterStr = fw.write(filter->jfilter);
-       }
-
-       int err = _ctx_history_query(data_type_str.c_str(), filterStr.c_str(), &((*list)->cursor));
-       IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Query failed");
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-// Data object manipulation
-EXPORT_API int context_history_list_get_count(context_history_list_h list, int* count)
-{
-       ASSERT_NOT_NULL(list && count);
-
-       unsigned int value;
-
-       int err = ctx_history_cursor_get_count(list->cursor, &value);
-       IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get count failed");
-
-       *count = value;
-       return E_NONE;
-}
-
-EXPORT_API int context_history_list_get_current(context_history_list_h list, context_history_record_h* record)
-{
-       ASSERT_NOT_NULL(list);
-       ASSERT_NOT_NULL(record);
-       *record = NULL;
-
-       unsigned int position = 0;
-       int err = ctx_history_cursor_get_position(list->cursor, &position);
-       IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get position failed");
-
-       *record = new(std::nothrow) _cx_history_record_handle();
-       ASSERT_ALLOC(*record);
-
-       (*record)->keys = list->cursor->keys;
-       (*record)->tuple = list->cursor->tuples[position];
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_list_move_first(context_history_list_h list)
-{
-       ASSERT_NOT_NULL(list);
-       return ctx_history_cursor_first(list->cursor);
-}
-
-EXPORT_API int context_history_list_move_next(context_history_list_h list)
-{
-       ASSERT_NOT_NULL(list);
-       return ctx_history_cursor_next(list->cursor);
-}
-
-EXPORT_API int context_history_list_destroy(context_history_list_h list)
-{
-       ASSERT_NOT_NULL(list);
-       ctx_history_cursor_destroy(list->cursor);
-       delete list;
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_get_int(context_history_record_h record, const char* key, int* val)
-{
-       ASSERT_NOT_NULL(record && val && key);
-
-       // Check key and data type
-       IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
-
-       int index = __getIndexOf(record, key);
-       IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
-
-       int64_t value;
-       IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &value), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
-
-       *val = value;
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_get_double(context_history_record_h record, const char* key, double* val)
-{
-       ASSERT_NOT_NULL(record && val && key);
-
-       // Check key and data type
-       IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
-
-       int index = __getIndexOf(record, key);
-       IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
-
-       IF_FAIL_RETURN_TAG(record->tuple->getAt(index, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_get_string(context_history_record_h record, const char* key, char** val)
-{
-       ASSERT_NOT_NULL(record && val && key);
-
-       // Check key and data type
-       IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_STRING, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
-
-       int index = __getIndexOf(record, key);
-       IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
-
-       std::string str;
-       IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &str), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
-
-       *val = g_strdup(str.c_str());
-       ASSERT_ALLOC(*val);
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-EXPORT_API int context_history_record_destroy(context_history_record_h record)
-{
-       ASSERT_NOT_NULL(record);
-       delete record;
-
-       return CONTEXT_HISTORY_ERROR_NONE;
-}
-
-std::string convert_filter_to_string(context_history_filter_e filter_type)
-{
-       std::string str;
-       switch (filter_type) {
-       case CONTEXT_HISTORY_FILTER_TIME_SPAN:
-               str = KEY_TIME_SPAN;
-               break;
-       case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
-               str = KEY_RESULT_SIZE;
-               break;
-       case CONTEXT_HISTORY_FILTER_APP_ID:
-               str = KEY_APP_ID;
-               break;
-       case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
-               str = KEY_DAY_OF_WEEK;
-               break;
-       case CONTEXT_HISTORY_FILTER_START_TIME:
-               str = KEY_START_TIME;
-               break;
-       case CONTEXT_HISTORY_FILTER_END_TIME:
-               str = KEY_END_TIME;
-               break;
-       case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
-               str = KEY_BSSID;
-               break;
-       case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
-               str = KEY_AUDIO_JACK;
-               break;
-       case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
-               str = KEY_COMMUNICATION_TYPE;
-               break;
-       default:
-               break;
-       }
-       return str;
-}
-
-std::string convert_data_to_string(context_history_data_e data_type)
-{
-       std::string str;
-       switch (data_type) {
-       case CONTEXT_HISTORY_RECENTLY_USED_APP:
-               str = SUBJ_APP_RECENTLY_USED;
-               break;
-       case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
-               str = SUBJ_APP_FREQUENTLY_USED;
-               break;
-       case CONTEXT_HISTORY_RARELY_USED_APP:
-               str = SUBJ_APP_RARELY_USED;
-               break;
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
-               str = SUBJ_APP_PEAK_TIME;
-               break;
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
-               str = SUBJ_MUSIC_PEAK_TIME;
-               break;
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
-               str = SUBJ_VIDEO_PEAK_TIME;
-               break;
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
-               str = SUBJ_APP_COMMON_SETTING;
-               break;
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
-               str = SUBJ_MUSIC_COMMON_SETTING;
-               break;
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
-               str = SUBJ_VIDEO_COMMON_SETTING;
-               break;
-       case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
-               str = SUBJ_SOCIAL_FREQ_ADDRESS;
-               break;
-       case CONTEXT_HISTORY_BATTERY_USAGE:
-               str = SUBJ_BATTERY_USAGE;
-               break;
-       case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
-               str = SUBJ_BATTERY_RECENT_USAGE;
-               break;
-       default:
-               break;
-       }
-       return str;
-}
-
-bool check_record_key_data_type(int type, std::string key)
-{
-       if ((key.compare(CONTEXT_HISTORY_APP_ID) == 0) ||
-                       key.compare(CONTEXT_HISTORY_ADDRESS) == 0) {
-               return (type == TYPE_STRING);
-       }
-
-       if ((key.compare(CONTEXT_HISTORY_TOTAL_COUNT) == 0) ||
-                       key.compare(CONTEXT_HISTORY_TOTAL_AMOUNT) == 0 ||
-                       key.compare(CONTEXT_HISTORY_TOTAL_DURATION) == 0 ||
-                       key.compare(CONTEXT_HISTORY_LAST_TIME) == 0 ||
-                       key.compare(CONTEXT_HISTORY_HOUR_OF_DAY) == 0 ||
-                       key.compare(CONTEXT_HISTORY_AUDIO_JACK) == 0 ||
-                       key.compare(CONTEXT_HISTORY_SYSTEM_VOLUME) == 0 ||
-                       key.compare(CONTEXT_HISTORY_MEDIA_VOLUME) == 0 ||
-                       key.compare(KEY_USED_TIME) == 0) {              // Internal use for RecentBatteryUsage
-               return (type == TYPE_NUMERIC);
-       }
-
-       return false;
-}
-
-bool check_filter_data_int(context_history_filter_e filter_type, int val)
-{
-       switch (filter_type) {
-       case CONTEXT_HISTORY_FILTER_TIME_SPAN:
-       case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
-       case CONTEXT_HISTORY_FILTER_START_TIME:
-       case CONTEXT_HISTORY_FILTER_END_TIME:
-               if (val > 0)
-                       return true;
-               break;
-       case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
-               if (val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKDAYS ||
-                       val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKENDS ||
-                       val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_ALL)
-                       return true;
-               break;
-       case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
-               if (val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_NOT_CONNECTED ||
-                       val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_CONNECTED)
-                       return true;
-               break;
-       case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
-               if (val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_CALL ||
-                       val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_MESSAGE ||
-                       val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_ALL)
-                       return true;
-               break;
-       default:
-               return false;
-       }
-       return false;
-}
-
-bool check_filter_data_string(context_history_filter_e filter_type, const char* val)
-{
-       IF_FAIL_RETURN(val, false);
-
-       switch (filter_type) {
-       case CONTEXT_HISTORY_FILTER_APP_ID:
-       case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
-               return (g_strstr_len(val, -1, ";") == NULL);
-
-       default:
-               return false;
-       }
-}
-
-bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter)
-{
-       /* This should be aligned with context_history_filter_e */
-       static const char *filter_key[FILTER_KEY_LIMIT] = {
-               NULL,
-               KEY_TIME_SPAN,
-               KEY_RESULT_SIZE,
-               KEY_APP_ID,
-               KEY_DAY_OF_WEEK,
-               KEY_START_TIME,
-               KEY_END_TIME,
-               KEY_BSSID,
-               KEY_AUDIO_JACK,
-               KEY_COMMUNICATION_TYPE,
-       };
-
-       bool allowed[FILTER_KEY_LIMIT] = {false};
-
-       allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = true;
-       allowed[CONTEXT_HISTORY_FILTER_START_TIME] = true;
-       allowed[CONTEXT_HISTORY_FILTER_END_TIME] = true;
-       allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = true;
-
-       switch (data_type) {
-       case CONTEXT_HISTORY_RECENTLY_USED_APP:
-       case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
-               allowed[CONTEXT_HISTORY_FILTER_WIFI_BSSID] = true;
-               allowed[CONTEXT_HISTORY_FILTER_AUDIO_JACK] = true;
-               break;
-
-       case CONTEXT_HISTORY_RARELY_USED_APP:
-               break;
-
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
-               allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
-               allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
-               break;
-
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
-               allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
-               break;
-
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
-               allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
-               allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
-               break;
-
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
-               allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
-               break;
-
-       case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
-               allowed[CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE] = true;
-               break;
-
-       case CONTEXT_HISTORY_BATTERY_USAGE:
-               break;
-
-       case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
-               allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = false;
-               allowed[CONTEXT_HISTORY_FILTER_START_TIME] = false;
-               allowed[CONTEXT_HISTORY_FILTER_END_TIME] = false;
-               break;
-
-       default:
-               return false;
-       }
-
-       bool found = true;
-       std::vector<std::string> keys = filter->jfilter.getMemberNames();
-
-       for (auto& key : keys) {
-               found = false;
-               for (int i = 1; i < FILTER_KEY_LIMIT; ++i) {
-                       if (allowed[i] && key == filter_key[i]) {
-                               found = true;
-                               break;
-                       }
-               }
-               if (found == true)
-                       continue;
-
-               return false;
-       }
-
-       return true;
-}
-
-int __getIndexOf(context_history_record_h record, const std::string& key)
-{
-       unsigned int i = 0;
-
-       for (i = 0; i < record->keys.size(); ++i) {
-               if (record->keys[i] == key) {
-                       return i;
-               }
-       }
-       return -1;
-}
-
-bool history_is_deprecated(context_history_data_e data_type)
-{
-       bool ret = false;
-       switch (data_type) {
-       case CONTEXT_HISTORY_RARELY_USED_APP:
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
-       case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
-       case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
-       case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
-               ret = true;
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-bool history_filter_is_deprecated(context_history_filter_e filter_type)
-{
-       bool ret = false;
-       switch (filter_type) {
-       case CONTEXT_HISTORY_FILTER_APP_ID:
-       case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
-       case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
-       case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
-               ret = true;
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
diff --git a/src/context_trigger.cpp b/src/context_trigger.cpp
deleted file mode 100644 (file)
index 941cc02..0000000
+++ /dev/null
@@ -1,1204 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#include <sstream>
-//#include <iomanip>
-#include <app_control_internal.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-#include <context_trigger.h>
-#include <context_trigger_internal.h>
-#include <Types.h>
-#include <DBusTypes.h>
-#include <CtxJson1.h>
-#include <DBusClient.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "TriggerOldRuleTypes.h"
-#include "rule_validator.h"
-#include "rule_util.h"
-
-#define TRIGGER_DEPRECATED_FUNCTION_MSG "DEPRECATION WARNING: %s is deprecated and will be removed from next release."
-#define TRIGGER_DEPRECATED_EVENT_MSG "DEPRECATION WARNING: This event is deprecated and will be removed from next release."
-#define TRIGGER_DEPRECATED_CONDITION_MSG "DEPRECATION WARNING: This condition is deprecated and will be removed from next release."
-
-//#define DOUBLE_PRECISION 2
-#define TYPE_EVENT 1
-#define TYPE_CONDITION 2
-#define TYPE_OPTION TRIG_TMPL_KEY_OPTION
-#define TYPE_ATTRIBUTE TRIG_TMPL_KEY_ATTRIBUTE
-#define OLD_INITIAL_ENTRY "{ \"" OLD_TRIG_RULE_KEY_DATA_ARR "\" : [ ] }"
-#define INITIAL_REF "{ \"" TRIG_TMPL_KEY_OPTION "\" : [ ], \"" TRIG_TMPL_KEY_ATTRIBUTE "\" : [ ] }"
-#define INITIAL_RULE \
-"{ \"" TRIG_RULE_KEY_DESCRIPTION "\" : \"\", \"" TRIG_RULE_KEY_EVENT "\" : { }, \"" TRIG_RULE_KEY_CONDITION "\" : [ ], \"" \
-TRIG_RULE_KEY_ACTION "\" : { }, \"" _TRIG_RULE_KEY_EXTRA "\": { } }"
-#define INITIAL_ENTRY "{ \"" TRIG_RULE_KEY_OPTION "\": { }, \"" TRIG_RULE_KEY_COMPARISON "\" : { } }"
-
-static ctx::DBusClient __dbusClient;
-
-static int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
-static int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
-static std::string convert_event_to_string(context_trigger_event_e item);
-static std::string convert_condition_to_string(context_trigger_condition_e item);
-static std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type);
-static std::string get_custom_item_subject(const char* provider, const char* item);
-static bool event_is_deprecated(context_trigger_event_e item);
-static bool condition_is_deprecated(context_trigger_condition_e item);
-
-//static std::string int_to_string(int value);
-//static std::string double_to_string(int value);
-
-typedef struct _context_trigger_rule_s {
-       ctx::CtxJson1 jold_rule;
-       ctx::CtxJson1 jrule;    // description, event{}, condition[], action{}, _extra{}
-       ctx::CtxJson1 jref;
-
-       _context_trigger_rule_s() {
-               jold_rule = EMPTY_JSON_OBJECT;
-               jrule = INITIAL_RULE;
-               jref = INITIAL_REF;
-       }
-} _context_trigger_rule_h;
-
-typedef struct _context_trigger_rule_entry_s {
-       int type;
-       ctx::CtxJson1 jentry;
-       ctx::CtxJson1 jref;
-
-       _context_trigger_rule_entry_s(int t): type(t) {
-               jentry = OLD_INITIAL_ENTRY;
-
-               if (t == TYPE_CONDITION) {
-                       jref = INITIAL_REF;
-               }
-       }
-} _context_trigger_rule_entry_h;
-
-// Add a rule
-SO_EXPORT int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && rule_id);
-
-       // Err: No event
-       if (!ctx::rule_util::isEventSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       // Err: No action
-       if (!ctx::rule_util::isActionSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       // If condition size isn't greater than 1, update logical operator as default
-       if ((rule->jrule).getSize(NULL, TRIG_RULE_KEY_CONDITION) <= 1) {
-               (rule->jrule).set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, TRIG_RULE_LOGICAL_CONJUNCTION);
-       }
-
-       ctx::CtxJson1 jrule_id;
-       int error = __dbusClient.write(SUBJ_TRIGGER_ADD, rule->jrule, &jrule_id);
-
-       if (error == ERR_NONE) {
-               jrule_id.get(NULL, TRIG_KEY_RULE_ID, rule_id);
-       }
-
-       return error;
-}
-
-// Remove a rule
-SO_EXPORT int context_trigger_remove_rule(int rule_id)
-{
-       _D("BEGIN");
-       if (rule_id <= 0)
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
-       ctx::CtxJson1 jrule_id;
-       jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
-       int error = __dbusClient.write(SUBJ_TRIGGER_REMOVE, jrule_id, NULL);
-
-       if (error == ERR_ALREADY_STARTED) {     // Rule is still enabled.
-               return CONTEXT_TRIGGER_ERROR_RULE_ENABLED;
-       } else if (error == ERR_NO_DATA) {
-               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       }
-
-       return error;
-}
-
-// Enable a rule
-SO_EXPORT int context_trigger_enable_rule(int rule_id)
-{
-       _D("BEGIN");
-       if (rule_id <= 0)
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
-       ctx::CtxJson1 jrule_id;
-       jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
-
-       int req_id;     // Useless in context_trigger
-       int error = __dbusClient.subscribe(SUBJ_TRIGGER_ENABLE, jrule_id, &req_id, NULL);
-
-       if (error == ERR_NO_DATA) {
-               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       }
-
-       return error;
-}
-
-// Disable a rule
-SO_EXPORT int context_trigger_disable_rule(int rule_id)
-{
-       _D("BEGIN");
-       if (rule_id <= 0)
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
-       ctx::CtxJson1 jrule_id;
-       jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
-       int error = __dbusClient.write(SUBJ_TRIGGER_DISABLE, jrule_id, NULL);
-
-       if (error == ERR_NO_DATA) {
-               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       }
-
-       return error;
-}
-
-SO_EXPORT int context_trigger_get_own_rule_ids(int** enabled_rule_ids, int* enabled_rule_count, int** disabled_rule_ids, int* disabled_rule_count)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(enabled_rule_ids && enabled_rule_count && disabled_rule_ids && disabled_rule_count);
-
-       int req_id;
-       ctx::CtxJson1 data_read;
-       int error = __dbusClient.readSync(SUBJ_TRIGGER_GET_RULE_IDS, NULL, &req_id, &data_read);
-
-       if (error != ERR_NONE) {
-               return error;
-       }
-
-       // Enabled rules
-       int* e_arr = NULL;
-       *enabled_rule_count = data_read.getSize(NULL, TRIG_KEY_ENABLED_IDS);
-
-       if (*enabled_rule_count > 0) {
-               e_arr = static_cast<int*>(g_malloc((*enabled_rule_count) * sizeof(int)));
-               IF_FAIL_RETURN_TAG(e_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
-
-               int id;
-               for (int i = 0; data_read.getAt(NULL, TRIG_KEY_ENABLED_IDS, i, &id); i++) {
-                       *(e_arr + i) = id;
-               }
-       }
-       *enabled_rule_ids = e_arr;
-
-       // Disabled rules
-       int* d_arr = NULL;
-       *disabled_rule_count = data_read.getSize(NULL, TRIG_KEY_DISABLED_IDS);
-
-       if (*disabled_rule_count > 0) {
-               d_arr = static_cast<int*>(g_malloc((*disabled_rule_count) * sizeof(int)));
-               IF_FAIL_RETURN_TAG(d_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
-
-               int id;
-               for (int i = 0; data_read.getAt(NULL, TRIG_KEY_DISABLED_IDS, i, &id); i++) {
-                       *(d_arr + i) = id;
-               }
-       }
-       *disabled_rule_ids = d_arr;
-
-       return error;
-}
-
-
-SO_EXPORT int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule);
-       if (rule_id <= 0)
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-
-       ctx::CtxJson1 option;
-       option.set(NULL, TRIG_KEY_RULE_ID, rule_id);
-
-       int req_id;
-       ctx::CtxJson1 data_read;
-       int error = __dbusClient.readSync(SUBJ_TRIGGER_GET, option, &req_id, &data_read);
-
-       if (error == ERR_NO_DATA) {
-               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       } else if (error != ERR_NONE) {
-               return error;
-       }
-
-       *rule = new(std::nothrow) _context_trigger_rule_h();
-       (*rule)->jrule = data_read;
-
-       return ERR_NONE;
-}
-
-// Rule creation
-SO_EXPORT int context_trigger_rule_create(context_trigger_logical_type_e logical_type, context_trigger_rule_h* rule)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule);
-
-       std::string logical_str = convert_logical_type_to_string(logical_type);
-       if (logical_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       *rule = new(std::nothrow) _context_trigger_rule_h();
-       (*rule)->jold_rule.set(NULL, OLD_TRIG_RULE_KEY_OPERATOR, logical_str);
-
-       (*rule)->jrule.set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, logical_str);
-
-       return ERR_NONE;
-}
-
-// Rule deletion
-SO_EXPORT int context_trigger_rule_destroy(context_trigger_rule_h rule)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule);
-       delete rule;
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-
-SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && entry);
-
-       // Check if rule handle is created
-       ctx::CtxJson1 extra;
-       bool ret = (rule->jrule).get(NULL, _TRIG_RULE_KEY_EXTRA, &extra);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER);
-
-       if (entry->type == TYPE_EVENT) {
-               // Err: More than one event
-               ctx::CtxJson1 elem;
-               if ((rule->jold_rule).get(NULL, OLD_TRIG_RULE_KEY_EVENT, &elem)) {
-                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-               }
-
-               // Err: Check if all the mandatory options are added
-               ret = ctx::rule_validator::check_option(entry->jentry);
-               IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-               // Err: If referential conditions are registered priviously, check them
-               std::string ename;
-               (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
-               ret = ctx::rule_validator::check_referential_data(ename, rule->jref);
-               IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-               ctx::CtxJson1 temp = (entry->jentry).str();
-               ret = (rule->jold_rule).set(NULL, OLD_TRIG_RULE_KEY_EVENT, temp);
-
-               int error = ctx::rule_util::setEvent(entry->jentry, &(rule->jrule));
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add event entry");
-       } else if (entry->type == TYPE_CONDITION) {
-               // Err: Condition without comparison data
-               if ((entry->jentry).getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) < 1) {
-                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-               }
-
-               ctx::CtxJson1 elem;
-               for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
-                       int val_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
-                       int op_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR);
-
-                       // Err: Condition without comparison data
-                       if (val_arr_size != op_arr_size || val_arr_size < 1 || op_arr_size < 1) {
-                               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-                       }
-
-                       // Err: Check if all the mandatory options are added
-                       ret = ctx::rule_validator::check_option(entry->jentry);
-                       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-                       // If event is already added ....
-                       std::string ename;
-                       ret = (rule->jold_rule).get(OLD_TRIG_RULE_KEY_EVENT, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
-                       if (ret) {
-                               // Err: Check referential information if exists
-                               ret = ctx::rule_validator::check_referential_data(ename, entry->jref);
-                               IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-                       } else {
-                               // If not, copy referential information to rule entry
-                               ctx::CtxJson1 info;
-                               for (int j = 0; (entry->jref).getAt(NULL, TYPE_OPTION, j, &info); j++) {
-                                       (rule->jref).append(NULL, TYPE_OPTION, info);
-                               }
-
-                               for (int j = 0; (entry->jref).getAt(NULL, TYPE_ATTRIBUTE, j, &info); j++) {
-                                       (rule->jref).append(NULL, TYPE_ATTRIBUTE, info);
-                               }
-                       }
-               }
-
-               ctx::CtxJson1 temp = (entry->jentry).str();
-               ret = (rule->jold_rule).append(NULL, OLD_TRIG_RULE_KEY_CONDITION, temp);
-
-               ctx::rule_util::addCondition(entry->jentry, &(rule->jrule));
-       } else {
-               // Entry is not created
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-static bool is_call_operation(app_control_h app_control)
-{
-       char *op = NULL;
-       int err = app_control_get_operation(app_control, &op);
-       IF_FAIL_RETURN_TAG(err == APP_CONTROL_ERROR_NONE, false, _W, "Getting operation of app control failed");
-
-       bool ret = STR_EQ(op, APP_CONTROL_OPERATION_CALL);
-       g_free(op);
-
-       return ret;
-}
-
-SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && app_control);
-       int error;
-
-       // Privilege check
-       error = __dbusClient.call(METHOD_CHK_PRIV_APPLAUNCH);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
-
-       if (is_call_operation(app_control)) {
-               error = __dbusClient.call(METHOD_CHK_PRIV_CALL);
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
-       }
-
-       // Err: if action arleady exists
-       if (ctx::rule_util::isActionSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       // Err: service app
-       char* app_id = NULL;
-       error = app_control_get_app_id(app_control, &app_id);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
-
-       pkgmgrinfo_appinfo_h app_info;
-       error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
-       g_free(app_id);
-       IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
-
-       // Service apps are not allowed to be launched (Mobile & Wearable)
-       char *app_type = NULL;
-       pkgmgrinfo_appinfo_get_component_type(app_info, &app_type);
-       if (!strcmp(app_type, "svcapp")) {
-               _E("Service application is restricted");
-               pkgmgrinfo_appinfo_destroy_appinfo(app_info);
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-       pkgmgrinfo_appinfo_destroy_appinfo(app_info);
-
-       // Set app control
-       bundle* appctl_bundle = NULL;
-       error = app_control_to_bundle(app_control, &appctl_bundle);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
-
-       bundle_raw* appctl_raw;
-       int raw_length;
-       error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
-
-       std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
-       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_APP_LAUNCH, TRIG_RULE_KEY_APP_LAUNCH_APP_CONTROL, appctl_str);
-       bundle_free_encoded_rawdata(&appctl_raw);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_set_action_notification(context_trigger_rule_h rule, const char* title, const char* content, const char* icon_path, app_control_h app_control)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && title && content);
-
-       // Privilege check
-       int error = __dbusClient.call(METHOD_CHK_PRIV_NOTIFICATION);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
-
-       // if action arleady exists
-       if (ctx::rule_util::isActionSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       // Err: App control check
-       if (app_control) {
-               char* app_id = NULL;
-               error = app_control_get_app_id(app_control, &app_id);
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
-
-               pkgmgrinfo_appinfo_h app_info;
-               error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
-               g_free(app_id);
-               IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
-
-               pkgmgrinfo_appinfo_destroy_appinfo(app_info);
-       }
-
-       // Set title, content
-       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_TITLE, title);
-       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_CONTENT, content);
-
-       // Set icon path
-       if (icon_path) {
-               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_ICON_PATH, icon_path);
-       }
-
-       // Set app control
-       if (app_control) {
-               bundle* appctl_bundle = NULL;
-               error = app_control_to_bundle(app_control, &appctl_bundle);
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
-
-               bundle_raw* appctl_raw;
-               int raw_length;
-               error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
-
-               std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
-               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_APP_CONTROL, appctl_str);
-
-               bundle_free_encoded_rawdata(&appctl_raw);
-       }
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_set_action_dbus_call(context_trigger_rule_h rule,
-               const char *bus_name, const char *object_path, const char *interface_name, const char *method_name, GVariant *param)
-{
-       ASSERT_NOT_NULL(rule && bus_name && object_path && interface_name && method_name);
-
-       /* if action arleady exists */
-       if (ctx::rule_util::isActionSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       /* Set basic dbus method call info */
-       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_NAME, bus_name);
-       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_OBJECT, object_path);
-       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_INTERFACE, interface_name);
-       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_METHOD, method_name);
-
-       /* Set the parameters */
-       if (param)
-               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_PARAMETER, param);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Set description
-SO_EXPORT int context_trigger_rule_set_description(context_trigger_rule_h rule, const char* description)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule);
-
-       (rule->jrule).set(NULL, TRIG_RULE_KEY_DESCRIPTION, description);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Get rule description
-SO_EXPORT int context_trigger_rule_get_description(context_trigger_rule_h rule, char** description)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && description);
-
-       std::string val;
-       (rule->jrule).get(NULL, TRIG_RULE_KEY_DESCRIPTION, &val);
-
-       *description = strdup(val.c_str());
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Event creation
-SO_EXPORT int context_trigger_rule_event_create(context_trigger_event_e event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry);
-
-       if (event_is_deprecated(event_item)) {
-               _W(TRIGGER_DEPRECATED_EVENT_MSG);
-       }
-
-       std::string eitem_str = convert_event_to_string(event_item);
-       if (eitem_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       int error = context_trigger_rule_event_create_internal(eitem_str.c_str(), logical_type, entry);
-       return error;
-}
-
-SO_EXPORT int context_trigger_rule_custom_event_create(const char* event_item, const char* provider, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(event_item && provider && entry);
-
-       // Err: Invalid provider
-       pkgmgrinfo_pkginfo_h pkg_info;
-       int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
-       pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
-       IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
-
-       std::string subject = get_custom_item_subject(provider, event_item);
-       error = context_trigger_rule_event_create_internal(subject.c_str(), logical_type, entry, true);
-
-       return error;
-}
-
-int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(event_item);
-
-       // Err: Invalid logical operator
-       std::string logical_str = convert_logical_type_to_string(logical_type);
-       if (logical_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       int error = ctx::rule_validator::request_template(event_item, is_custom);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
-
-       *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_EVENT);
-       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, event_item);
-       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, logical_str);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Event availability check
-SO_EXPORT int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(supported);
-
-       if (event_is_deprecated(event_item)) {
-               _W(TRIGGER_DEPRECATED_EVENT_MSG);
-       }
-
-       *supported = false;
-
-       std::string eitem_str = convert_event_to_string(event_item);
-       if (eitem_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       int error = __dbusClient.isSupported(eitem_str);
-
-       if (error == ERR_NONE)
-               *supported = true;
-
-       if (error == ERR_NOT_SUPPORTED)
-               return ERR_NONE;
-
-       return error;
-}
-
-// Condition creation
-SO_EXPORT int context_trigger_rule_condition_create(context_trigger_condition_e condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry);
-
-       if (condition_is_deprecated(condition_item)) {
-               _W(TRIGGER_DEPRECATED_CONDITION_MSG);
-       }
-
-       std::string citem_str = convert_condition_to_string(condition_item);
-       if (citem_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       int error = context_trigger_rule_condition_create_internal(citem_str.c_str(), logical_type, entry);
-       return error;
-}
-
-SO_EXPORT int context_trigger_rule_custom_condition_create(const char* condition_item, const char* provider, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(condition_item && provider && entry);
-
-       // Err: Invalid provider
-       pkgmgrinfo_pkginfo_h pkg_info;
-       int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
-       pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
-       IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
-
-       std::string subject = get_custom_item_subject(provider, condition_item);
-       error = context_trigger_rule_condition_create_internal(subject.c_str(), logical_type, entry, true);
-       return error;
-}
-
-int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(condition_item);
-
-       std::string logical_str = convert_logical_type_to_string(logical_type);
-       if (logical_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       int error = ctx::rule_validator::request_template(condition_item, is_custom);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
-
-       *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_CONDITION);
-       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, condition_item);
-       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, logical_str);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-// Condition availability check
-SO_EXPORT int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(supported);
-
-       if (condition_is_deprecated(condition_item)) {
-               _W(TRIGGER_DEPRECATED_CONDITION_MSG);
-       }
-
-       *supported = false;
-
-       std::string citem_str = convert_condition_to_string(condition_item);
-       if (citem_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       int error = __dbusClient.isSupported(citem_str);
-
-       if (error == ERR_NONE)
-               *supported = true;
-
-       if (error == ERR_NOT_SUPPORTED)
-               return ERR_NONE;
-
-       return error;
-}
-
-// Rule data deletion
-SO_EXPORT int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry);
-       delete entry;
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_option_int(context_trigger_rule_entry_h entry, const char* option_key, int value)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry && option_key);
-
-       bool ret = true;
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
-       ret = ctx::rule_validator::check_option_int(name, option_key, value);
-       if (!ret) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_option_string(context_trigger_rule_entry_h entry, const char* option_key, const char* value)
-{
-       _D("BEGIN");
-       _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
-       ASSERT_NOT_NULL(entry && option_key && value);
-
-       bool ret = true;
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
-       ret = ctx::rule_validator::check_option_string(name, option_key, value);
-       if (!ret) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h entry, const char* option_key, const char* event_data_key)
-{
-       _D("BEGIN");
-       _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
-       ASSERT_NOT_NULL(entry && option_key && event_data_key);
-
-       // Err: Only conditin can reference data from event
-       if (entry->type != TYPE_CONDITION) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
-
-       // Err: Check if key is valid
-       bool ret = ctx::rule_validator::check_valid_key(TYPE_OPTION, name, option_key);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-       // Set reference information
-       ret = ctx::rule_validator::set_ref_info(TYPE_OPTION, &(entry->jref), name, option_key, event_data_key);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
-
-       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_key(context_trigger_rule_entry_h entry, context_trigger_logical_type_e logical_type, const char* key)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry && key);
-
-       std::string logical_str = convert_logical_type_to_string(logical_type);
-       if (logical_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
-
-       // Err: Check if key is valid
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
-       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-       // Err: Comparison key is already added
-       ctx::CtxJson1 elem;
-       for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
-               std::string elem_item;
-               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
-               // Err: Comparison key is already added
-               if (elem_item.compare(key) == 0) {
-                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-               }
-       }
-
-       ctx::CtxJson1 data;
-       data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, key);
-       data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR, logical_str);
-       (entry->jentry).append(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, data);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-static int context_trigger_rule_entry_add_comparison_string_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, std::string value)
-{
-       ctx::CtxJson1 elem;
-       for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
-               std::string elem_item;
-               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
-
-               if (elem_item.compare(key) == 0) {
-                       std::string elem_val;
-                       std::string elem_op;
-                       for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
-                               elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
-
-                               // Err: Duplicated <operator, value>
-                               if (elem_val.compare(value) == 0 && elem_op.compare(op) == 0) {
-                                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-                               }
-                       }
-                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value.c_str());
-                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
-                       (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
-
-                       return CONTEXT_TRIGGER_ERROR_NONE;
-               }
-       }
-
-       // Comparison key not exist
-       return CONTEXT_TRIGGER_ERROR_NO_DATA;
-}
-
-static int context_trigger_rule_entry_add_comparison_int_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, int value)
-{
-       ctx::CtxJson1 elem;
-       for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
-               std::string elem_item;
-               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
-
-               if (elem_item.compare(key) == 0) {
-                       int elem_val;
-                       std::string elem_op;
-                       for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
-                               elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
-
-                               // Err: Duplicated <operator, value>
-                               if (elem_val == value && elem_op.compare(op) == 0) {
-                                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-                               }
-                       }
-                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value);
-                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
-                       (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
-
-                       return CONTEXT_TRIGGER_ERROR_NONE;
-               }
-       }
-
-       // Comparison key not exist
-       return CONTEXT_TRIGGER_ERROR_NO_DATA;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* event_data_key)
-{
-       _D("BEGIN");
-       _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
-       ASSERT_NOT_NULL(entry && key && op && event_data_key);
-
-       // Err: Only condition can reference data from event
-       if (entry->type != TYPE_CONDITION) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
-
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
-
-       // Err: Check if key is valid
-       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-       // Err: Invalid operator
-       std::string type = ctx::rule_validator::get_data_type_from_template(TYPE_ATTRIBUTE, name, key);
-       ret = ctx::rule_validator::is_valid_operator(type, op);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-       int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
-       IF_FAIL_RETURN(error == ERR_NONE, error);
-
-       // Set reference information
-       ret = ctx::rule_validator::set_ref_info(TYPE_ATTRIBUTE, &(entry->jref), name, key, event_data_key);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
-
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
-
-SO_EXPORT int context_trigger_rule_entry_add_comparison_int(context_trigger_rule_entry_h entry, const char* key, const char* op, int value)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry && key && op);
-
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
-       bool ret = ctx::rule_validator::check_comparison_int(name, key, op, value);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-       int error = context_trigger_rule_entry_add_comparison_int_internal(entry, key, op, value);
-       return error;
-}
-/*
-SO_EXPORT int context_trigger_rule_entry_add_comparison_double(context_trigger_rule_entry_h entry, const char* key, const char* op, double value)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry && key && op);
-
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
-       // TODO: check_comparison_double()
-       bool ret = ctx::rule_validator::check_comparison_double(name, key, op, value);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-       int error = context_trigger_rule_entry_add_comparison_internal(entry, key, op, double_to_string(value));
-       return error;
-}
-*/
-SO_EXPORT int context_trigger_rule_entry_add_comparison_string(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* value)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(entry && key && op && value);
-
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
-       bool ret = ctx::rule_validator::check_comparison_string(name, key, op, value);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
-
-       int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, value);
-       return error;
-}
-
-SO_EXPORT int context_trigger_custom_register(const char* name, const char* attr_template)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(name && attr_template);
-
-       // Err: Invalid CtxJson1
-       ctx::CtxJson1 jattr_template = attr_template;
-       IF_FAIL_RETURN_TAG(jattr_template.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Failed to parse template");
-
-       // Err: Invalid template
-       bool ret = ctx::rule_validator::is_valid_template(jattr_template);
-       IF_FAIL_RETURN_TAG(ret, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid template");
-
-       ctx::CtxJson1 data;
-       data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_ADD);
-       data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
-       data.set(NULL, TRIG_TMPL_KEY_ATTRIBUTE, jattr_template);
-
-       int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add custom item: %#x", error);
-
-       return error;
-}
-
-SO_EXPORT int context_trigger_custom_unregister(const char* name)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(name);
-
-       ctx::CtxJson1 data;
-       data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_REMOVE);
-       data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
-
-       ctx::CtxJson1 subj;
-       int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, &subj);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to remove custom item: %#x", error);
-
-       std::string subject;
-       subj.get(NULL, TRIG_TMPL_KEY_SUBJECT, &subject);
-       ctx::rule_validator::remove_template(subject);
-
-       return error;
-}
-
-SO_EXPORT int context_trigger_custom_publish(const char* name, const char* fact)
-{
-       _D("BEGIN");
-       ASSERT_NOT_NULL(name && fact);
-
-       // Err: Invalid CtxJson1
-       ctx::CtxJson1 jfact = fact;
-       IF_FAIL_RETURN_TAG(jfact.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Cannot parse fact CtxJson1");
-
-       ctx::CtxJson1 data;
-       data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_PUBLISH);
-       data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
-       data.set(NULL, TRIG_CUSTOM_KEY_FACT, jfact);
-
-       int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to publish custom data");
-
-       return error;
-}
-
-std::string convert_event_to_string(context_trigger_event_e item)
-{
-       std::string str;
-       switch (item) {
-       case CONTEXT_TRIGGER_EVENT_TIME:
-               str = SUBJ_STATE_ALARM;
-               break;
-       case CONTEXT_TRIGGER_EVENT_BATTERY:
-               str = SUBJ_STATE_BATTERY;
-               break;
-       case CONTEXT_TRIGGER_EVENT_CHARGER:
-               str = SUBJ_STATE_CHARGER;
-               break;
-       case CONTEXT_TRIGGER_EVENT_GPS:
-               str = SUBJ_STATE_GPS;
-               break;
-       case CONTEXT_TRIGGER_EVENT_HEADPHONE:
-               str = SUBJ_STATE_HEADPHONE;
-               break;
-       case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
-               str = SUBJ_STATE_PSMODE;
-               break;
-       case CONTEXT_TRIGGER_EVENT_USB:
-               str = SUBJ_STATE_USB;
-               break;
-       case CONTEXT_TRIGGER_EVENT_WIFI:
-               str = SUBJ_STATE_WIFI;
-               break;
-       case CONTEXT_TRIGGER_EVENT_CALL:
-               str = SUBJ_STATE_CALL;
-               break;
-       case CONTEXT_TRIGGER_EVENT_EMAIL:
-               str = SUBJ_STATE_EMAIL;
-               break;
-       case CONTEXT_TRIGGER_EVENT_MESSAGE:
-               str = SUBJ_STATE_MESSAGE;
-               break;
-       case CONTEXT_TRIGGER_EVENT_CONTACTS:
-               str = SUBJ_STATE_CONTACTS;
-               break;
-       case CONTEXT_TRIGGER_EVENT_ACTIVITY_STATIONARY:
-               str = SUBJ_ACTIVITY_STATIONARY;
-               break;
-       case CONTEXT_TRIGGER_EVENT_ACTIVITY_WALKING:
-               str = SUBJ_ACTIVITY_WALKING;
-               break;
-       case CONTEXT_TRIGGER_EVENT_ACTIVITY_RUNNING:
-               str = SUBJ_ACTIVITY_RUNNING;
-               break;
-       case CONTEXT_TRIGGER_EVENT_ACTIVITY_IN_VEHICLE:
-               str = SUBJ_ACTIVITY_IN_VEHICLE;
-               break;
-       case CONTEXT_TRIGGER_EVENT_PLACE:
-               str = SUBJ_PLACE_GEOFENCE;
-               break;
-       default:
-               break;
-       }
-       return str;
-}
-
-std::string convert_condition_to_string(context_trigger_condition_e item)
-{
-       std::string str;
-       switch (item) {
-       case CONTEXT_TRIGGER_CONDITION_TIME:
-               str = SUBJ_STATE_TIME;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_BATTERY:
-               str = SUBJ_STATE_BATTERY;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_CHARGER:
-               str = SUBJ_STATE_CHARGER;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_GPS:
-               str = SUBJ_STATE_GPS;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_HEADPHONE:
-               str = SUBJ_STATE_HEADPHONE;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
-               str = SUBJ_STATE_PSMODE;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_USB:
-               str = SUBJ_STATE_USB;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_WIFI:
-               str = SUBJ_STATE_WIFI;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_CALL:
-               str = SUBJ_STATE_CALL;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
-               str = SUBJ_APP_FREQUENCY;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
-               str = SUBJ_SOCIAL_FREQUENCY;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
-               str = SUBJ_MUSIC_FREQUENCY;
-               break;
-       case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
-               str = SUBJ_VIDEO_FREQUENCY;
-               break;
-       default:
-               break;
-       }
-       return str;
-}
-
-std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type)
-{
-       std::string str;
-       switch (logical_type) {
-       case CONTEXT_TRIGGER_LOGICAL_CONJUNCTION:
-               str = TRIG_RULE_LOGICAL_CONJUNCTION;
-               break;
-       case CONTEXT_TRIGGER_LOGICAL_DISJUNCTION:
-               str = TRIG_RULE_LOGICAL_DISJUNCTION;
-               break;
-       default:
-               break;
-       }
-       return str;
-}
-
-std::string get_custom_item_subject(const char* provider, const char* item)
-{
-       std::string subject_name = std::string(TRIG_CUSTOM_PREFIX TRIG_SUBJECT_SEPERATOR) + provider + std::string(TRIG_SUBJECT_SEPERATOR) + item;
-       return subject_name;
-}
-
-bool event_is_deprecated(context_trigger_event_e item)
-{
-       bool ret = false;
-       switch (item) {
-       case CONTEXT_TRIGGER_EVENT_TIME:
-       case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
-       case CONTEXT_TRIGGER_EVENT_CALL:
-       case CONTEXT_TRIGGER_EVENT_EMAIL:
-       case CONTEXT_TRIGGER_EVENT_MESSAGE:
-               ret = true;
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-bool condition_is_deprecated(context_trigger_condition_e item)
-{
-       bool ret = false;
-       switch (item) {
-       case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
-       case CONTEXT_TRIGGER_CONDITION_CALL:
-       case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
-       case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
-       case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
-       case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
-               ret = true;
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-/*
-std::string int_to_string(int value)
-{
-       std::ostringstream ostr;
-       ostr << value;
-       return ostr.str();
-}
-
-std::string double_to_string(int value)
-{
-       std::ostringstream ostr;
-       ostr.imbue(std::locale("C"));
-       ostr << std::setprecision(DOUBLE_PRECISION) << std::fixed << value;
-       return ostr.str();
-}*/
diff --git a/src/history/context_history.cpp b/src/history/context_history.cpp
new file mode 100644 (file)
index 0000000..3770d2f
--- /dev/null
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <json/json.h>
+#include <ContextTypes.h>
+#include <Tuple.h>
+#include <app_history_internal.h>
+#include <app_history_types_internal.h>
+#include <AppHistoryTypes.h>
+#include <context_history.h>
+
+#define HISTORY_DEPRECATED_DATA "DEPRECATION WARNING: This history data type is deprecated and will be removed from next release"
+#define HISTORY_DEPRECATED_FILTER "DEPRECATION WARNING: This history filter is deprecated and will be removed from next release"
+#define TYPE_NUMERIC 0
+#define TYPE_STRING 1
+#define FILTER_KEY_LIMIT 10
+
+#define ASSERT_ALLOC(X)                IF_FAIL_RETURN_TAG(X, E_NO_MEM, _E, "Memory allocation failed")
+#define ASSERT_NOT_NULL(X)     IF_FAIL_RETURN_TAG(X, E_PARAM, _E, "Parameter null")
+
+// handles
+typedef struct _context_history_handle_s {
+       /* At this point, this handle has no purpose.
+          But, it will be used to support other functionalities later,
+          e.g., async read or session management. */
+       int tmp;
+} _cx_history_handle;
+
+typedef struct _context_history_filter_handle_s {
+       Json::Value jfilter;
+} _cx_history_filter_handle;
+
+typedef struct _context_history_list_handle_s {
+       ctx_history_cursor_h cursor;
+
+       _context_history_list_handle_s() {
+               cursor = NULL;
+       }
+} _cx_history_list_handle;
+
+typedef struct _context_history_record_handle_s {
+       std::vector<std::string> keys;
+       std::shared_ptr<ctx::Tuple> tuple;
+} _cx_history_record_handle;
+
+static std::string convert_filter_to_string(context_history_filter_e filter_type);
+static std::string convert_data_to_string(context_history_data_e data_type);
+static bool check_record_key_data_type(int type, std::string key);
+static bool check_filter_data_int(context_history_filter_e filter_type, int val);
+static bool check_filter_data_string(context_history_filter_e filter_type, const char* val);
+static bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter);
+static int __getIndexOf(context_history_record_h record, const std::string& key);
+static bool history_is_deprecated(context_history_data_e data_type);
+static bool history_filter_is_deprecated(context_history_filter_e filter_type);
+
+// life-cycle
+EXPORT_API int context_history_create(context_history_h* handle)
+{
+       ASSERT_NOT_NULL(handle);
+
+       *handle = new(std::nothrow) _cx_history_handle();
+       ASSERT_ALLOC(*handle);
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_destroy(context_history_h handle)
+{
+       ASSERT_NOT_NULL(handle);
+       delete handle;
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+// Read filter manipulation
+EXPORT_API int context_history_filter_create(context_history_filter_h* filter)
+{
+       ASSERT_NOT_NULL(filter);
+
+       *filter = new(std::nothrow) _cx_history_filter_handle();
+       ASSERT_ALLOC(*filter);
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_filter_destroy(context_history_filter_h filter)
+{
+       ASSERT_NOT_NULL(filter);
+       delete filter;
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_filter_set_int(context_history_filter_h filter, context_history_filter_e filter_type, int val)
+{
+       ASSERT_NOT_NULL(filter);
+
+       if (history_filter_is_deprecated(filter_type)) {
+               _W(HISTORY_DEPRECATED_FILTER);
+       }
+
+       std::string filter_str = convert_filter_to_string(filter_type);
+       if (filter_str.empty()) {
+               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+       }
+
+       // Check filter and its data type
+       IF_FAIL_RETURN_TAG(check_filter_data_int(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
+
+       filter->jfilter[filter_str] = val;
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_filter_set_string(context_history_filter_h filter, context_history_filter_e filter_type, const char* val)
+{
+       ASSERT_NOT_NULL(filter);
+       ASSERT_NOT_NULL(val);
+
+       _W("DEPRECATION WARNING: context_history_filter_set_string() is deprecated and will be removed from next release.");
+       if (history_filter_is_deprecated(filter_type)) {
+               _W(HISTORY_DEPRECATED_FILTER);
+       }
+
+       std::string filter_str = convert_filter_to_string(filter_type);
+       if (filter_str.empty()) {
+               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+       }
+
+       // Check filter and its data type
+       IF_FAIL_RETURN_TAG(check_filter_data_string(filter_type, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Filter type mismatched");
+
+       filter->jfilter[filter_str] = val;
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_is_supported(context_history_data_e data_type, bool* supported)
+{
+       ASSERT_NOT_NULL(supported);
+
+       if (history_is_deprecated(data_type)) {
+               _W(HISTORY_DEPRECATED_DATA);
+       }
+
+       std::string data_type_str = convert_data_to_string(data_type);
+       if (data_type_str.empty()) {
+               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+       }
+
+       return ctx_history_is_supported(data_type_str.c_str(), supported);
+}
+
+EXPORT_API int context_history_get_list(context_history_h handle, context_history_data_e data_type, context_history_filter_h filter, context_history_list_h* list)
+{
+       ASSERT_NOT_NULL(handle);
+       ASSERT_NOT_NULL(list);
+       *list = NULL;
+
+       if (history_is_deprecated(data_type)) {
+               _W(HISTORY_DEPRECATED_DATA);
+       }
+       /*TODO: Boundary check for filter values has to be done*/
+
+       std::string data_type_str = convert_data_to_string(data_type);
+       if (data_type_str.empty()) {
+               return CONTEXT_HISTORY_ERROR_INVALID_PARAMETER;
+       }
+
+       // Check data type & filter
+       if (filter)
+               IF_FAIL_RETURN_TAG(check_invalid_filter(data_type, filter), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid filter key");
+
+       *list = new(std::nothrow) _cx_history_list_handle();
+       ASSERT_ALLOC(*list);
+
+       std::string filterStr;
+       if (filter) {
+               Json::FastWriter fw;
+               fw.omitEndingLineFeed();
+               filterStr = fw.write(filter->jfilter);
+       }
+
+       int err = _ctx_history_query(data_type_str.c_str(), filterStr.c_str(), &((*list)->cursor));
+       IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Query failed");
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+// Data object manipulation
+EXPORT_API int context_history_list_get_count(context_history_list_h list, int* count)
+{
+       ASSERT_NOT_NULL(list && count);
+
+       unsigned int value;
+
+       int err = ctx_history_cursor_get_count(list->cursor, &value);
+       IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get count failed");
+
+       *count = value;
+       return E_NONE;
+}
+
+EXPORT_API int context_history_list_get_current(context_history_list_h list, context_history_record_h* record)
+{
+       ASSERT_NOT_NULL(list);
+       ASSERT_NOT_NULL(record);
+       *record = NULL;
+
+       unsigned int position = 0;
+       int err = ctx_history_cursor_get_position(list->cursor, &position);
+       IF_FAIL_RETURN_TAG(err == E_NONE, err, _E, "Get position failed");
+
+       *record = new(std::nothrow) _cx_history_record_handle();
+       ASSERT_ALLOC(*record);
+
+       (*record)->keys = list->cursor->keys;
+       (*record)->tuple = list->cursor->tuples[position];
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_list_move_first(context_history_list_h list)
+{
+       ASSERT_NOT_NULL(list);
+       return ctx_history_cursor_first(list->cursor);
+}
+
+EXPORT_API int context_history_list_move_next(context_history_list_h list)
+{
+       ASSERT_NOT_NULL(list);
+       return ctx_history_cursor_next(list->cursor);
+}
+
+EXPORT_API int context_history_list_destroy(context_history_list_h list)
+{
+       ASSERT_NOT_NULL(list);
+       ctx_history_cursor_destroy(list->cursor);
+       delete list;
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_get_int(context_history_record_h record, const char* key, int* val)
+{
+       ASSERT_NOT_NULL(record && val && key);
+
+       // Check key and data type
+       IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
+
+       int index = __getIndexOf(record, key);
+       IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
+
+       int64_t value;
+       IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &value), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
+
+       *val = value;
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_get_double(context_history_record_h record, const char* key, double* val)
+{
+       ASSERT_NOT_NULL(record && val && key);
+
+       // Check key and data type
+       IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_NUMERIC, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
+
+       int index = __getIndexOf(record, key);
+       IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
+
+       IF_FAIL_RETURN_TAG(record->tuple->getAt(index, val), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_get_string(context_history_record_h record, const char* key, char** val)
+{
+       ASSERT_NOT_NULL(record && val && key);
+
+       // Check key and data type
+       IF_FAIL_RETURN_TAG(check_record_key_data_type(TYPE_STRING, key), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Data type mismatched");
+
+       int index = __getIndexOf(record, key);
+       IF_FAIL_RETURN_TAG(index >= 0, CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid record key");
+
+       std::string str;
+       IF_FAIL_RETURN_TAG(record->tuple->getAt(index, &str), CONTEXT_HISTORY_ERROR_INVALID_PARAMETER, _E, "Invalid data");
+
+       *val = g_strdup(str.c_str());
+       ASSERT_ALLOC(*val);
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+EXPORT_API int context_history_record_destroy(context_history_record_h record)
+{
+       ASSERT_NOT_NULL(record);
+       delete record;
+
+       return CONTEXT_HISTORY_ERROR_NONE;
+}
+
+std::string convert_filter_to_string(context_history_filter_e filter_type)
+{
+       std::string str;
+       switch (filter_type) {
+       case CONTEXT_HISTORY_FILTER_TIME_SPAN:
+               str = KEY_TIME_SPAN;
+               break;
+       case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
+               str = KEY_RESULT_SIZE;
+               break;
+       case CONTEXT_HISTORY_FILTER_APP_ID:
+               str = KEY_APP_ID;
+               break;
+       case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
+               str = KEY_DAY_OF_WEEK;
+               break;
+       case CONTEXT_HISTORY_FILTER_START_TIME:
+               str = KEY_START_TIME;
+               break;
+       case CONTEXT_HISTORY_FILTER_END_TIME:
+               str = KEY_END_TIME;
+               break;
+       case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
+               str = KEY_BSSID;
+               break;
+       case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
+               str = KEY_AUDIO_JACK;
+               break;
+       case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
+               str = KEY_COMMUNICATION_TYPE;
+               break;
+       default:
+               break;
+       }
+       return str;
+}
+
+std::string convert_data_to_string(context_history_data_e data_type)
+{
+       std::string str;
+       switch (data_type) {
+       case CONTEXT_HISTORY_RECENTLY_USED_APP:
+               str = SUBJ_APP_RECENTLY_USED;
+               break;
+       case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
+               str = SUBJ_APP_FREQUENTLY_USED;
+               break;
+       case CONTEXT_HISTORY_RARELY_USED_APP:
+               str = SUBJ_APP_RARELY_USED;
+               break;
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
+               str = SUBJ_APP_PEAK_TIME;
+               break;
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
+               str = SUBJ_MUSIC_PEAK_TIME;
+               break;
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
+               str = SUBJ_VIDEO_PEAK_TIME;
+               break;
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
+               str = SUBJ_APP_COMMON_SETTING;
+               break;
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
+               str = SUBJ_MUSIC_COMMON_SETTING;
+               break;
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
+               str = SUBJ_VIDEO_COMMON_SETTING;
+               break;
+       case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
+               str = SUBJ_SOCIAL_FREQ_ADDRESS;
+               break;
+       case CONTEXT_HISTORY_BATTERY_USAGE:
+               str = SUBJ_BATTERY_USAGE;
+               break;
+       case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
+               str = SUBJ_BATTERY_RECENT_USAGE;
+               break;
+       default:
+               break;
+       }
+       return str;
+}
+
+bool check_record_key_data_type(int type, std::string key)
+{
+       if ((key.compare(CONTEXT_HISTORY_APP_ID) == 0) ||
+                       key.compare(CONTEXT_HISTORY_ADDRESS) == 0) {
+               return (type == TYPE_STRING);
+       }
+
+       if ((key.compare(CONTEXT_HISTORY_TOTAL_COUNT) == 0) ||
+                       key.compare(CONTEXT_HISTORY_TOTAL_AMOUNT) == 0 ||
+                       key.compare(CONTEXT_HISTORY_TOTAL_DURATION) == 0 ||
+                       key.compare(CONTEXT_HISTORY_LAST_TIME) == 0 ||
+                       key.compare(CONTEXT_HISTORY_HOUR_OF_DAY) == 0 ||
+                       key.compare(CONTEXT_HISTORY_AUDIO_JACK) == 0 ||
+                       key.compare(CONTEXT_HISTORY_SYSTEM_VOLUME) == 0 ||
+                       key.compare(CONTEXT_HISTORY_MEDIA_VOLUME) == 0 ||
+                       key.compare(KEY_USED_TIME) == 0) {              // Internal use for RecentBatteryUsage
+               return (type == TYPE_NUMERIC);
+       }
+
+       return false;
+}
+
+bool check_filter_data_int(context_history_filter_e filter_type, int val)
+{
+       switch (filter_type) {
+       case CONTEXT_HISTORY_FILTER_TIME_SPAN:
+       case CONTEXT_HISTORY_FILTER_RESULT_SIZE:
+       case CONTEXT_HISTORY_FILTER_START_TIME:
+       case CONTEXT_HISTORY_FILTER_END_TIME:
+               if (val > 0)
+                       return true;
+               break;
+       case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
+               if (val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKDAYS ||
+                       val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_WEEKENDS ||
+                       val == CONTEXT_HISTORY_FILTER_DAY_OF_WEEK_ALL)
+                       return true;
+               break;
+       case CONTEXT_HISTORY_FILTER_AUDIO_JACK:
+               if (val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_NOT_CONNECTED ||
+                       val == CONTEXT_HISTORY_FILTER_AUDIO_JACK_CONNECTED)
+                       return true;
+               break;
+       case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
+               if (val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_CALL ||
+                       val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_MESSAGE ||
+                       val == CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE_ALL)
+                       return true;
+               break;
+       default:
+               return false;
+       }
+       return false;
+}
+
+bool check_filter_data_string(context_history_filter_e filter_type, const char* val)
+{
+       IF_FAIL_RETURN(val, false);
+
+       switch (filter_type) {
+       case CONTEXT_HISTORY_FILTER_APP_ID:
+       case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
+               return (g_strstr_len(val, -1, ";") == NULL);
+
+       default:
+               return false;
+       }
+}
+
+bool check_invalid_filter(context_history_data_e data_type, context_history_filter_h filter)
+{
+       /* This should be aligned with context_history_filter_e */
+       static const char *filter_key[FILTER_KEY_LIMIT] = {
+               NULL,
+               KEY_TIME_SPAN,
+               KEY_RESULT_SIZE,
+               KEY_APP_ID,
+               KEY_DAY_OF_WEEK,
+               KEY_START_TIME,
+               KEY_END_TIME,
+               KEY_BSSID,
+               KEY_AUDIO_JACK,
+               KEY_COMMUNICATION_TYPE,
+       };
+
+       bool allowed[FILTER_KEY_LIMIT] = {false};
+
+       allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = true;
+       allowed[CONTEXT_HISTORY_FILTER_START_TIME] = true;
+       allowed[CONTEXT_HISTORY_FILTER_END_TIME] = true;
+       allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = true;
+
+       switch (data_type) {
+       case CONTEXT_HISTORY_RECENTLY_USED_APP:
+       case CONTEXT_HISTORY_FREQUENTLY_USED_APP:
+               allowed[CONTEXT_HISTORY_FILTER_WIFI_BSSID] = true;
+               allowed[CONTEXT_HISTORY_FILTER_AUDIO_JACK] = true;
+               break;
+
+       case CONTEXT_HISTORY_RARELY_USED_APP:
+               break;
+
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
+               allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
+               allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
+               break;
+
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
+               allowed[CONTEXT_HISTORY_FILTER_DAY_OF_WEEK] = true;
+               break;
+
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
+               allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
+               allowed[CONTEXT_HISTORY_FILTER_APP_ID] = true;
+               break;
+
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
+               allowed[CONTEXT_HISTORY_FILTER_RESULT_SIZE] = false;
+               break;
+
+       case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
+               allowed[CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE] = true;
+               break;
+
+       case CONTEXT_HISTORY_BATTERY_USAGE:
+               break;
+
+       case CONTEXT_HISTORY_RECENT_BATTERY_USAGE:
+               allowed[CONTEXT_HISTORY_FILTER_TIME_SPAN] = false;
+               allowed[CONTEXT_HISTORY_FILTER_START_TIME] = false;
+               allowed[CONTEXT_HISTORY_FILTER_END_TIME] = false;
+               break;
+
+       default:
+               return false;
+       }
+
+       bool found = true;
+       std::vector<std::string> keys = filter->jfilter.getMemberNames();
+
+       for (auto& key : keys) {
+               found = false;
+               for (int i = 1; i < FILTER_KEY_LIMIT; ++i) {
+                       if (allowed[i] && key == filter_key[i]) {
+                               found = true;
+                               break;
+                       }
+               }
+               if (found == true)
+                       continue;
+
+               return false;
+       }
+
+       return true;
+}
+
+int __getIndexOf(context_history_record_h record, const std::string& key)
+{
+       unsigned int i = 0;
+
+       for (i = 0; i < record->keys.size(); ++i) {
+               if (record->keys[i] == key) {
+                       return i;
+               }
+       }
+       return -1;
+}
+
+bool history_is_deprecated(context_history_data_e data_type)
+{
+       bool ret = false;
+       switch (data_type) {
+       case CONTEXT_HISTORY_RARELY_USED_APP:
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_APP:
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_MUSIC:
+       case CONTEXT_HISTORY_PEAK_TIME_FOR_VIDEO:
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_APP:
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_MUSIC:
+       case CONTEXT_HISTORY_COMMON_SETTING_FOR_VIDEO:
+       case CONTEXT_HISTORY_FREQUENTLY_COMMUNICATED_ADDRESS:
+               ret = true;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
+bool history_filter_is_deprecated(context_history_filter_e filter_type)
+{
+       bool ret = false;
+       switch (filter_type) {
+       case CONTEXT_HISTORY_FILTER_APP_ID:
+       case CONTEXT_HISTORY_FILTER_DAY_OF_WEEK:
+       case CONTEXT_HISTORY_FILTER_WIFI_BSSID:
+       case CONTEXT_HISTORY_FILTER_COMMUNICATION_TYPE:
+               ret = true;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
diff --git a/src/rule_util.cpp b/src/rule_util.cpp
deleted file mode 100644 (file)
index f57de01..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <map>
-#include <list>
-#include <context_trigger.h>
-#include <Types.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include <TimerManager.h>
-#include "rule_validator.h"
-#include "rule_util.h"
-#include "ComparisonConverter.h"
-#include "IntComparisonConverter.h"
-#include "StringComparisonConverter.h"
-
-using namespace ctx;
-
-static bool __handleTimerEvent(CtxJson1& event);
-static int __arrangeDayOfWeek(CtxJson1& dayInfo);
-
-int ctx::rule_util::setEvent(CtxJson1& entry, CtxJson1* rule)
-{
-       CtxJson1 tempEvent;
-       std::string subject;
-       entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &subject);
-
-       CtxJson1 option;
-       entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPTION, &option);
-       tempEvent.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
-
-       CtxJson1 elem;
-       for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
-               CtxJson1 newElem;
-
-               std::string key;
-               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
-
-               std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
-
-               ComparisonConverter* converter = NULL;
-               if (type == TRIG_TMPL_TYPE_INTEGER) {
-                       converter = new(std::nothrow) IntComparisonConverter(elem);
-               } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
-                       converter = new(std::nothrow) StringComparisonConverter(elem);
-               }
-               IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
-               converter->getResult(&newElem);
-
-               CtxJson1 detail;
-               newElem.get(NULL, key.c_str(), &detail);
-
-               std::string path = subject + "." + TRIG_RULE_KEY_COMPARISON;
-               tempEvent.set(path.c_str(), key.c_str(), detail);
-               delete converter;
-       }
-
-       // Handle Timer Event
-       if (subject.compare(SUBJ_STATE_ALARM) == 0) {
-               IF_FAIL_RETURN(__handleTimerEvent(tempEvent), ERR_INVALID_RULE);
-       }
-
-       rule->set(NULL, TRIG_RULE_KEY_EVENT, tempEvent);
-
-       // Save event entry's logical to extra info (default and)
-       std::string eventOp = TRIG_RULE_LOGICAL_CONJUNCTION;
-       if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
-               entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, &eventOp);
-       }
-       rule->set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, eventOp);
-
-       return ERR_NONE;
-}
-
-int ctx::rule_util::addCondition(CtxJson1& entry, CtxJson1* rule)
-{
-       CtxJson1 tempCond;
-       std::string subject;
-       entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &subject);
-
-       CtxJson1 option;
-       entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPTION, &option);
-       tempCond.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
-
-       CtxJson1 elem;
-       for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
-               CtxJson1 newElem;
-
-               std::string key;
-               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
-
-               std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
-
-               ComparisonConverter* converter = NULL;
-               if (type == TRIG_TMPL_TYPE_INTEGER) {
-                       converter = new(std::nothrow) IntComparisonConverter(elem);
-               } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
-                       converter = new(std::nothrow) StringComparisonConverter(elem);
-               }
-               IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
-               converter->getResult(&newElem);
-
-               tempCond.set(subject.c_str(), TRIG_RULE_KEY_COMPARISON, newElem);
-               delete converter;
-       }
-
-       rule->append(NULL, TRIG_RULE_KEY_CONDITION, tempCond);
-
-       // Save event entry's logical to extra info (default and)
-       std::string condOp = TRIG_RULE_LOGICAL_CONJUNCTION;
-       if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
-               entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, &condOp);
-       }
-       rule->append(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, condOp);
-
-       return ERR_NONE;
-}
-
-bool __handleTimerEvent(CtxJson1& event)
-{
-       CtxJson1 alarmComp;
-       bool ret = event.get(SUBJ_STATE_ALARM, TRIG_RULE_KEY_COMPARISON, &alarmComp);
-       IF_FAIL_RETURN_TAG(ret, false, _E, "Invalid EVENT_TIME event");
-
-       // Day processing
-       CtxJson1 dayInfo;
-       bool daySpecified = alarmComp.get(NULL, KEY_DAY_OF_WEEK, &dayInfo);
-
-       if (daySpecified) {
-               CtxJson1 newDayInfo;
-               newDayInfo.set(NULL, TRIG_RULE_KEY_OPERATOR, TRIG_RULE_OP_ONE_OF);
-
-               int dow = __arrangeDayOfWeek(dayInfo);
-               IF_FAIL_RETURN_TAG(dow > 0, false, _E, "Invalid DayOfWeek info for EVENT_TIME");
-
-               for (int i = 0 ; i < DAYS_PER_WEEK; i++) {
-                       int d = 0x01 << i;
-                       if (dow & d) {
-                               std::string day = TimerManager::dowToStr(d);
-                               newDayInfo.append(NULL, TRIG_RULE_KEY_VALUE, day);
-
-                               // Copy details as option
-                               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, day);
-                       }
-               }
-               event.set(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_COMPARISON, KEY_DAY_OF_WEEK, newDayInfo);
-       } else {
-               // If DayOfWeek is not specified, regard it as Mon ~ Sun
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_MON);
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_TUE);
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_WED);
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_THU);
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_FRI);
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SAT);
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SUN);
-       }
-
-       // Time processing
-       CtxJson1 timeInfo;
-       alarmComp.get(NULL, KEY_TIME_OF_DAY, &timeInfo);
-
-       int time;
-       std::string timeOp;
-       timeInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &timeOp);
-
-       if (timeOp == TRIG_RULE_OP_EQUAL_TO) {
-               timeInfo.get(NULL, TRIG_RULE_KEY_VALUE, &time);
-               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
-       } else if (timeOp == TRIG_RULE_OP_ONE_OF) {
-               for (int i = 0; timeInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &time); i++) {
-                       event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
-               }
-       }
-
-       return true;
-}
-
-int __arrangeDayOfWeek(CtxJson1& dayInfo)
-{
-       std::string dayOp;
-       if (!dayInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &dayOp)) {
-               return TimerManager::dowToInt(DOW_EVERYDAY);
-       }
-
-       int result = 0;
-       if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO || dayOp == TRIG_RULE_OP_NOT_IN) {
-               result = TimerManager::dowToInt(DOW_EVERYDAY);
-       }
-
-       int dow;
-       std::string day;
-       if (dayOp == TRIG_RULE_OP_EQUAL_TO) {
-               dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
-               dow = TimerManager::dowToInt(day);
-               result |= dow;
-       } else if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO) {
-               dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
-               dow = TimerManager::dowToInt(day);
-               dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
-               result &= dow;
-       } else if (dayOp == TRIG_RULE_OP_ONE_OF) {
-               for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
-                       dow = TimerManager::dowToInt(day);
-                       result |= dow;
-               }
-       } else if (dayOp == TRIG_RULE_OP_NONE_OF) {
-               for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
-                       dow = TimerManager::dowToInt(day);
-                       dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
-                       result &= dow;
-               }
-       }
-
-       _D("Requested day of week (%#x)", result);
-       return result;
-}
-
-bool ctx::rule_util::isEventSet(CtxJson1& rule)
-{
-       ctx::CtxJson1 event;
-       if (rule.get(NULL, TRIG_RULE_KEY_EVENT, &event)) {
-               if (event != EMPTY_JSON_OBJECT) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-bool ctx::rule_util::isActionSet(CtxJson1& rule)
-{
-       ctx::CtxJson1 action;
-       if (rule.get(NULL, TRIG_RULE_KEY_ACTION, &action)) {
-               if (action != EMPTY_JSON_OBJECT) {
-                       return true;
-               }
-       }
-
-       return false;
-}
diff --git a/src/rule_util.h b/src/rule_util.h
deleted file mode 100644 (file)
index d4443bb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __CONTEXT_RULE_UTIL_H__
-#define __CONTEXT_RULE_UTIL_H__
-
-#include <CtxJson1.h>
-
-namespace ctx {
-
-       namespace rule_util {
-
-               int setEvent(CtxJson1& entry, CtxJson1* rule);
-               int addCondition(CtxJson1& entry, CtxJson1* rule);
-               bool isEventSet(CtxJson1& rule);
-               bool isActionSet(CtxJson1& rule);
-
-       }
-}      /* namespace ctx */
-
-#endif /* __CONTEXT_RULE_UTIL_H__ */
diff --git a/src/rule_validator.cpp b/src/rule_validator.cpp
deleted file mode 100644 (file)
index 6f37448..0000000
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sstream>
-#include <string>
-#include <map>
-#include <Types.h>
-#include <context_trigger.h>
-#include <TriggerTypes.h>
-#include <TriggerRuleTypes.h>
-#include "DBusClient.h"
-#include "TriggerOldRuleTypes.h"
-#include "rule_validator.h"
-
-using namespace ctx;
-
-#define RULE_VALIDATOR_COND_NAME "name"
-#define RULE_VALIDATOR_KEY "key"
-#define RULE_VALIDATOR_TYPE "type"
-#define RULE_VALIDATOR_REF "ref"
-
-typedef std::map<std::string, CtxJson1> template_map_t;
-template_map_t template_map;   // <name, template>
-
-static int string_to_int(std::string str);
-static bool check_value_int(CtxJson1& tmpl, std::string key, int value);
-static bool check_value_string(CtxJson1& tmpl, std::string key, std::string value);
-static bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value);
-static CtxJson1 get_template(std::string name);
-static bool check_template_int(CtxJson1& elem);
-static bool check_template_string(CtxJson1& elem);
-static bool check_template_enum(CtxJson1& elem);
-static std::string get_data_type(CtxJson1& elem, std::string& key);
-static bool is_equal_type(std::string& type1, std::string& type2);
-
-int string_to_int(std::string str)
-{
-       int i;
-       std::istringstream convert(str);
-
-       if (!(convert >> i))
-               i = 0;
-
-       return i;
-}
-
-CtxJson1 get_template(std::string name)
-{
-       rule_validator::request_template(name);
-       return template_map[name];
-}
-
-int rule_validator::request_template(std::string name, bool mandatory)
-{
-       if (!mandatory) {
-               template_map_t::iterator it = template_map.find(name);
-               IF_FAIL_RETURN(it == template_map.end(), ERR_NONE);
-       }
-
-       // Request template
-       CtxJson1 request;
-       request.set(NULL, TRIG_TMPL_KEY_SUBJECT, name);
-
-       int req_id;
-       CtxJson1 tmpl;
-       DBusClient dbusClient;
-       int error = dbusClient.readSync(SUBJ_TRIGGER_GET_TEMPLATE, request, &req_id, &tmpl);
-       if (error == ERR_NOT_SUPPORTED) {
-               template_map.erase(name);
-               _E("Failed to get request: not supported");
-               return ERR_NOT_SUPPORTED;
-       }
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get request");
-
-       template_map[name] = tmpl;
-
-       return ERR_NONE;
-}
-
-void rule_validator::remove_template(std::string name)
-{
-       template_map.erase(name);
-}
-
-// called by context_trigger_rule_add_entry()
-bool rule_validator::check_option(CtxJson1& item)
-{
-       std::string name;
-       item.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
-
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
-       // No option needed
-       CtxJson1 opt_tmpl;
-       tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
-
-       std::list<std::string> opt_keys;
-       IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
-       if (opt_keys.size() <= 0) {
-               return true;
-       }
-
-       // Err: Check if mandatory option is missed
-       std::string val_str;
-       int val;
-       if (name == SUBJ_PLACE_GEOFENCE) {
-               if (!(item.get(OLD_TRIG_RULE_KEY_EVENT_OPTION, CONTEXT_TRIGGER_PLACE_ID, &val)))
-                       return false;
-       } else if (name == SUBJ_APP_FREQUENCY) {
-               if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_APP_ID, &val_str)))
-                       return false;
-       } else if (name == SUBJ_SOCIAL_FREQUENCY) {
-               if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_ADDRESS, &val_str)))
-                       return false;
-       }
-
-       return true;
-}
-
-// called by context_trigger_rule_entry_add_option_int()
-bool rule_validator::check_option_int(std::string name, std::string key, int value)
-{
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
-       CtxJson1 opt_tmpl;
-       tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
-
-       // Err: Item with no option
-       std::list<std::string> opt_keys;
-       IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
-       IF_FAIL_RETURN(opt_keys.size() > 0, false);
-
-       // Err: Invalid option key or Invalid value type
-       std::string t_type = get_data_type(opt_tmpl, key);
-       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
-
-       // Err: Inappropriate value
-       //   a. normal case
-       bool ret = check_value_int(opt_tmpl, key, value);
-       IF_FAIL_RETURN(ret, false);
-
-       return true;
-}
-
-// called by context_trigger_rule_entry_add_option_string()
-bool rule_validator::check_option_string(std::string name, std::string key, std::string value)
-{
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
-       CtxJson1 opt_tmpl;
-       tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
-
-       // Err: ';' for SQL injection
-       IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
-
-       // Err: Item with no option
-       std::list<std::string> opt_keys;
-       IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
-       IF_FAIL_RETURN(opt_keys.size() > 0, false);
-
-       // Err: Invalid option key or Invalid value type
-       std::string t_type = get_data_type(opt_tmpl, key);
-       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
-
-       // Err: Inappropriate value
-       //   a. spacial case
-       if (t_type == TRIG_TMPL_TYPE_STRING && (name == SUBJ_APP_FREQUENCY || name == SUBJ_SOCIAL_FREQUENCY
-                       || name == SUBJ_MUSIC_FREQUENCY || name == SUBJ_VIDEO_FREQUENCY)
-                       && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
-               std::size_t found = value.find("-");
-               if (found == std::string::npos) {
-                       return false;
-               }
-
-               int t1 = string_to_int(value.substr(0, found-1));
-               int t2 = string_to_int(value.substr(found+1, value.length()-1));
-
-               if (!(t1 >= 0 && t1 < 24) || !(t2 >= 0 && t2 < 24)) {
-                       return false;
-               }
-
-               if (t1 >= t2) {
-                       return false;
-               }
-
-               return true;
-       }
-
-       //   b. normal case
-       bool ret = false;
-       if (t_type == TRIG_TMPL_TYPE_STRING) {
-               ret = check_value_string(opt_tmpl, key, value);
-       } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
-               ret = check_value_enum(opt_tmpl, key, value);
-       }
-
-       return ret;
-}
-
-// called by context_trigger_rule_entry_add_comparison_int()
-bool rule_validator::check_comparison_int(std::string name, std::string key, std::string op, int value)
-{
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
-       CtxJson1 attr_tmpl;
-       tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
-
-       // Err: Invalid attribute key or Invalid value type
-       std::string t_type = get_data_type(attr_tmpl, key);
-       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
-
-       // Err: Invalid operator for the value
-       //    a. normal case
-       bool ret = is_valid_operator(TRIG_TMPL_TYPE_INTEGER, op);
-       IF_FAIL_RETURN(ret, false);
-       //    b. special case
-       if (name == SUBJ_STATE_ALARM && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
-               IF_FAIL_RETURN(op == CONTEXT_TRIGGER_EQUAL_TO, false);
-       }
-
-       // Err: Inappropriate value
-       //    a. normal case
-       ret = check_value_int(attr_tmpl, key, value);
-       IF_FAIL_RETURN(ret, false);
-
-       return true;
-}
-
-// called by context_trigger_rule_entry_add_comparison_string()
-bool rule_validator::check_comparison_string(std::string name, std::string key, std::string op, std::string value)
-{
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != CtxJson1(EMPTY_JSON_OBJECT), false);
-
-       CtxJson1 attr_tmpl;
-       tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
-
-       // Err: ';' for SQL injection
-       IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
-
-       // Err: Invalid option key or Invalid value type
-       std::string t_type = get_data_type(attr_tmpl, key);
-       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
-
-       // Err: Invalid operator for the value
-       bool ret = is_valid_operator(t_type, op);
-       IF_FAIL_RETURN(ret, false);
-
-       // Err: Inappropriate value
-       //    a. normal case
-       if (t_type == TRIG_TMPL_TYPE_STRING) {
-               ret = check_value_string(attr_tmpl, key, value);
-               IF_FAIL_RETURN(ret, false);
-       } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
-               ret = check_value_enum(attr_tmpl, key, value);
-               IF_FAIL_RETURN(ret, false);
-       }
-
-       return true;
-}
-
-bool rule_validator::check_valid_key(std::string type, std::string name, std::string key)
-{
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
-       // Err: Invalid key
-       CtxJson1 tmp;
-       bool ret = tmpl.get(type.c_str(), key.c_str(), &tmp);
-       IF_FAIL_RETURN(ret, false);
-
-       return true;
-}
-
-bool check_value_int(CtxJson1& tmpl, std::string key, int value)
-{
-       int min, max;
-
-       if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MIN, &min)) {
-               IF_FAIL_RETURN(value >= min, false);
-       }
-
-       if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MAX, &max)) {
-               IF_FAIL_RETURN(value <= max, false);
-       }
-
-       return true;
-}
-
-bool check_value_string(CtxJson1& tmpl, std::string key, std::string value)
-{
-       return true;
-}
-
-bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value)
-{
-       std::string t_val;
-       for (int i = 0; tmpl.getAt(key.c_str(), TRIG_TMPL_TYPE_ENUM, i, &t_val); i++) {
-               if (t_val == value)
-                       return true;
-       }
-
-       return false;
-}
-
-// called by context_trigger_rule_entry_add_comparison()
-// called by context_trigger_rule_entry_add_option()
-bool rule_validator::set_ref_info(std::string type, CtxJson1* jref, std::string name, std::string key, std::string ref_data)
-{
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
-
-       CtxJson1 detailed_tmpl;
-       tmpl.get(NULL, type.c_str(), &detailed_tmpl);
-
-       std::string dt = get_data_type(detailed_tmpl, key);
-       IF_FAIL_RETURN(dt == TRIG_TMPL_TYPE_INTEGER || dt == TRIG_TMPL_TYPE_STRING || dt == TRIG_TMPL_TYPE_ENUM, false);
-
-       CtxJson1 temp;
-       temp.set(NULL, RULE_VALIDATOR_COND_NAME, name);
-       temp.set(NULL, RULE_VALIDATOR_KEY, key);
-       temp.set(NULL, RULE_VALIDATOR_TYPE, dt);
-       temp.set(NULL, RULE_VALIDATOR_REF, ref_data);
-
-       if (type == TRIG_TMPL_KEY_OPTION) {
-               jref->append(NULL, TRIG_TMPL_KEY_OPTION, temp);
-       } else if (type == TRIG_TMPL_KEY_ATTRIBUTE) {
-               jref->append(NULL, TRIG_TMPL_KEY_ATTRIBUTE, temp);
-       } else {
-               return false;
-       }
-
-       return true;;
-}
-
-std::string get_data_type(CtxJson1& elem, std::string& key)
-{
-       std::string data_type;
-       bool ret = elem.get(key.c_str(), TRIG_TMPL_KEY_TYPE, &data_type);
-       if (!ret) {
-               int size = elem.getSize(key.c_str(), TRIG_TMPL_TYPE_ENUM);
-               IF_FAIL_RETURN(size > 0, "");
-               data_type = TRIG_TMPL_TYPE_ENUM;
-       }
-       IF_FAIL_RETURN(data_type == TRIG_TMPL_TYPE_INTEGER || data_type == TRIG_TMPL_TYPE_STRING || data_type == TRIG_TMPL_TYPE_ENUM, "");
-
-       return data_type;
-}
-
-// called by context_trigger_rule_entry_add_comparison()
-std::string rule_validator::get_data_type_from_template(std::string type, std::string name, std::string key)
-{
-       CtxJson1 tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, "");
-
-       CtxJson1 detailed_tmpl;
-       tmpl.get(NULL, type.c_str(), &detailed_tmpl);
-
-       return get_data_type(detailed_tmpl, key);
-}
-
-// called by context_trigger_rule_add_entry()
-bool rule_validator::check_referential_data(std::string name, CtxJson1& ref_info)
-{
-       std::map<std::string, std::string> type_map;
-
-       CtxJson1 ref_data;
-       for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_OPTION, i, &ref_data); i++) {
-               std::string ref_key;
-               ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
-               std::string cond_type;
-               ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
-
-               if (type_map.count(ref_key) == 0) {
-                       type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
-               }
-
-               // Err: Invalid key or Value type not matched
-               IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
-       }
-
-       for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_ATTRIBUTE, i, &ref_data); i++) {
-               std::string ref_key;
-               ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
-               std::string cond_type;
-               ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
-
-               if (type_map.count(ref_key) == 0) {
-                       type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
-               }
-
-               // Err: Invalid key or Value type not matched
-               IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
-       }
-
-       return true;
-}
-
-bool is_equal_type(std::string& type1, std::string& type2)
-{
-       // This function regards TRIG_TMPL_TYPE_ENUM as TRIG_TMPL_TYPE_STRING for referential data
-       if (type1 == type2) {
-               return true;
-       }
-
-       if ((type1 == TRIG_TMPL_TYPE_STRING || type1 == TRIG_TMPL_TYPE_ENUM) && (type2 == TRIG_TMPL_TYPE_STRING || type2 == TRIG_TMPL_TYPE_ENUM)) {
-               return true;
-       }
-
-       return false;
-}
-
-bool rule_validator::is_valid_operator(std::string type, std::string op)
-{
-       if (op == CONTEXT_TRIGGER_EQUAL_TO || op == CONTEXT_TRIGGER_NOT_EQUAL_TO) {
-               return true;
-       }
-
-       if (type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_DOUBLE) {
-               if (op == CONTEXT_TRIGGER_GREATER_THAN || op == CONTEXT_TRIGGER_GREATER_THAN_OR_EQUAL_TO ||
-                       op == CONTEXT_TRIGGER_LESS_THAN || op == CONTEXT_TRIGGER_LESS_THAN_OR_EQUAL_TO) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-// For custom item template
-bool rule_validator::is_valid_template(CtxJson1& attr_template)
-{
-       IF_FAIL_RETURN_TAG(attr_template != EMPTY_JSON_OBJECT, false, _E, "Custom template: empty CtxJson1");
-
-       bool ret;
-       std::list<std::string> keys;
-       attr_template.getKeys(&keys);
-
-       for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); it++) {
-               std::string key = *it;
-
-               std::string type = get_data_type(attr_template, key);
-               IF_FAIL_RETURN_TAG(type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM,
-                       false, _E, "Custom template: invalid data type");
-
-               CtxJson1 elem;
-               attr_template.get(NULL, key.c_str(), &elem);
-               if (type == TRIG_TMPL_TYPE_INTEGER) {
-                       ret = check_template_int(elem);
-                       IF_FAIL_RETURN(ret, false);
-               } else if (type == TRIG_TMPL_TYPE_STRING) {
-                       ret = check_template_string(elem);
-                       IF_FAIL_RETURN(ret, false);
-               } else if (type == TRIG_TMPL_TYPE_ENUM) {
-                       ret = check_template_enum(elem);
-                       IF_FAIL_RETURN(ret, false);
-               }
-       }
-
-       return true;
-}
-
-bool check_template_int(CtxJson1& elem)
-{
-       std::list<std::string> elem_keys;
-       elem.getKeys(&elem_keys);
-
-       bool min = false;
-       bool max = false;
-       int min_val = 0;
-       int max_val = 0;
-
-       for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
-               std::string elem_key = *it2;
-               if (elem_key == TRIG_TMPL_KEY_MIN) {
-                       min = elem.get(NULL, elem_key.c_str(), &min_val);
-                       IF_FAIL_RETURN_TAG(min, false, _E, "Custom template: failed to get integer type value");
-               } else if (elem_key == TRIG_TMPL_KEY_MAX) {
-                       max = elem.get(NULL, elem_key.c_str(), &max_val);
-                       IF_FAIL_RETURN_TAG(max, false, _E, "Custom template: failed to get integer type value");
-               } else {
-                       IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
-               }
-       }
-
-       if (min && max) {
-               IF_FAIL_RETURN_TAG(min_val <= max_val, false, _E, "Custom template: invalid min, max value");
-       }
-
-       return true;
-}
-
-bool check_template_string(CtxJson1& elem)
-{
-       std::list<std::string> elem_keys;
-       elem.getKeys(&elem_keys);
-
-       for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
-               std::string elem_key = *it2;
-               IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
-       }
-
-       return true;
-}
-
-bool check_template_enum(CtxJson1& elem)
-{
-       std::list<std::string> elem_keys;
-       elem.getKeys(&elem_keys);
-
-       for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
-               std::string elem_key = *it2;
-
-               if (elem_key == TRIG_TMPL_TYPE_ENUM) {
-                       int size = elem.getSize(NULL, TRIG_TMPL_TYPE_ENUM);
-                       IF_FAIL_RETURN_TAG(size > 0, false, _E, "Custom template: invalid enum");
-
-                       std::string val_str;
-                       for (int i = 0; i < size; i++) {
-                               bool ret = elem.getAt(NULL, TRIG_TMPL_TYPE_ENUM, i, &val_str);
-                               IF_FAIL_RETURN_TAG(ret, false, _E, "Custom template: failed to get string type value");
-                       }
-               } else {
-                       IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
-               }
-       }
-
-       return true;
-}
diff --git a/src/rule_validator.h b/src/rule_validator.h
deleted file mode 100644 (file)
index 688a295..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __CONTEXT_RULE_VALIDATOR_H__
-#define __CONTEXT_RULE_VALIDATOR_H__
-
-#include <CtxJson1.h>
-
-namespace ctx {
-       namespace rule_validator {
-
-               int request_template(std::string name, bool mandatory = false);
-               void remove_template(std::string name);
-               bool check_option(ctx::CtxJson1 &item);
-               bool check_option_int(std::string name, std::string key, int value);
-               bool check_option_string(std::string name, std::string key, std::string value);
-               bool check_option_reference(std::string event, ctx::CtxJson1 &item);
-               bool check_comparison_int(std::string name, std::string key, std::string op, int value);
-               bool check_comparison_string(std::string name, std::string key, std::string op, std::string value);
-               bool check_valid_key(std::string type, std::string name, std::string key);
-
-               bool set_ref_info(std::string type, ctx::CtxJson1 *jref, std::string name, std::string key, std::string ref_key);
-               std::string get_data_type_from_template(std::string type, std::string name, std::string key);
-               bool check_referential_data(std::string name, ctx::CtxJson1 &ref_info);
-               bool is_valid_operator(std::string type, std::string op);
-
-               bool is_valid_template(ctx::CtxJson1& attr_template);
-       }
-}      /* namespace ctx */
-
-#endif /* __CONTEXT_RULE_VALIDATOR_H__ */
diff --git a/src/trigger/ComparisonConverter.cpp b/src/trigger/ComparisonConverter.cpp
new file mode 100644 (file)
index 0000000..3d73626
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "ComparisonConverter.h"
+
+using namespace ctx;
+
+ComparisonConverter::ComparisonConverter(const char* type, CtxJson1& info) :
+       __completed(false),
+       __size(0),
+       __logicalOp(TRIG_RULE_LOGICAL_DISJUNCTION),
+       __type(type),
+       __info(info.str()),
+       __result(EMPTY_JSON_OBJECT)
+{
+       __info.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &__key);
+       __info.get(NULL, OLD_TRIG_RULE_KEY_OPERATOR, &__logicalOp);
+       __size = __info.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
+}
+
+int ComparisonConverter::getResult(CtxJson1* result)
+{
+       if (__result == EMPTY_JSON_OBJECT)
+               return ERR_INVALID_RULE;
+
+       *result = __result.str();
+
+       return ERR_NONE;
+}
+
+void ComparisonConverter::__convertComparison()
+{
+       IF_FAIL_VOID(!__convertEmptyComparison());
+       IF_FAIL_VOID(!__convertSingleComparison());
+       IF_FAIL_VOID(!__convertMultipleComparison());
+
+       _E("Failed to convert comparison as new format");
+}
+
+bool ComparisonConverter::__convertEmptyComparison()
+{
+       IF_FAIL_RETURN(__size == 0, false);
+
+       CtxJson1 temp = EMPTY_JSON_OBJECT;
+       __result.set(NULL, __key.c_str(), temp);
+
+       return true;
+}
+
+bool ComparisonConverter::__convertSingleComparison()
+{
+       IF_FAIL_RETURN(__size == 1, false);
+
+       std::string op;
+       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, 0, &op);
+
+       __setConvertedOperator(op);
+       __setComparisonValue();
+
+       return true;
+}
+
+bool ComparisonConverter::__convertMultipleComparison()
+{
+       IF_FAIL_RETURN(__size > 1, false);
+
+       if (__checkOneOf()) {
+               return true;
+       } else if (__checkNoneOf()) {
+               return true;
+       } else if (__checkEtc()) {
+               return true;
+       }
+
+       return false;
+}
+
+bool ComparisonConverter::__checkOneOf()
+{
+       // Or of {==, ...}
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
+       IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_EQUAL_TO), false);
+
+       __setConvertedOperator(TRIG_RULE_OP_ONE_OF);
+       __setComparisonValueArray();
+
+       return true;
+}
+
+bool ComparisonConverter::__checkNoneOf()
+{
+       // And of {!=, ...}
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
+       IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_NOT_EQUAL_TO), false);
+
+       __setConvertedOperator(TRIG_RULE_OP_NONE_OF);
+       __setComparisonValueArray();
+
+       return true;
+}
+
+bool ComparisonConverter::__checkEtc()
+{
+       return false;
+}
+
+void ComparisonConverter::__setConvertedOperator(std::string op)
+{
+       __result.set(__key.c_str(), TRIG_RULE_KEY_OPERATOR, op);
+}
+
+void ComparisonConverter::__setComparisonValue()
+{
+       std::string valStr;
+       int val;
+
+       if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &valStr)) {
+               __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
+       } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &val)) {
+               __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
+       }
+}
+
+void ComparisonConverter::__setComparisonValueArray()
+{
+       std::string valStr;
+       int val;
+       // TODO sort
+       for (int i = 0; i < __size; i++) {
+               if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &valStr)) {
+                       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
+               } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val)) {
+                       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
+               }
+       }
+}
+
diff --git a/src/trigger/ComparisonConverter.h b/src/trigger/ComparisonConverter.h
new file mode 100644 (file)
index 0000000..9cde85c
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_COMPARISON_CONVERTER_H_
+#define _CONTEXT_COMPARISON_CONVERTER_H_
+
+#include <CtxJson1.h>
+#include "TriggerOldRuleTypes.h"
+
+namespace ctx {
+
+       class ComparisonConverter {
+       public:
+               virtual ~ComparisonConverter() {};
+
+               int getResult(CtxJson1* result);
+
+       protected:
+               bool __completed;
+               int __size;
+               std::string __logicalOp;
+               std::string __type;
+               CtxJson1 __info;
+               CtxJson1 __result;
+               std::string __key;
+
+               ComparisonConverter(const char* type, CtxJson1& info);
+               void __convertComparison();
+               virtual int __getOperatorCount(std::string op) = 0;
+               virtual bool __checkEtc();
+               void __setConvertedOperator(std::string op);
+
+       private:
+               bool __convertEmptyComparison();
+               bool __convertSingleComparison();
+               bool __convertMultipleComparison();
+               bool __checkOneOf();
+               bool __checkNoneOf();
+               void __setComparisonValue();
+               void __setComparisonValueArray();
+       };
+
+}      /* namespace ctx */
+
+#endif /* _CONTEXT_COMPARISON_CONVERTER_H_ */
diff --git a/src/trigger/IntComparisonConverter.cpp b/src/trigger/IntComparisonConverter.cpp
new file mode 100644 (file)
index 0000000..9f1a4e5
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <map>
+#include <list>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "IntComparisonConverter.h"
+
+using namespace ctx;
+
+IntComparisonConverter::IntComparisonConverter(CtxJson1 info) :
+       ComparisonConverter(TRIG_TMPL_TYPE_INTEGER, info)
+{
+       if (__size >= 2) {
+               for (int i = 0; i < __size; i++) {
+                       int val;
+                       std::string op;
+                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val);
+                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
+
+                       __insertComparisonInfo(op, val);
+               }
+               __sort();
+       }
+
+       __convertComparison();
+}
+
+void IntComparisonConverter::__insertComparisonInfo(std::string op, int val)
+{
+       IntComparisonMap::iterator it = __map.find(op);
+       if (it == __map.end()) {
+               IntList list;
+               list.push_back(val);
+               __map[op] = list;
+       } else {
+               it->second.push_back(val);
+       }
+}
+
+void IntComparisonConverter::__sort()
+{
+       for (IntComparisonMap::iterator it = __map.begin(); it != __map.end(); it++) {
+               it->second.sort();
+       }
+}
+
+int IntComparisonConverter::__getOperatorCount(std::string op)
+{
+       return __map[op].size();
+}
+
+int IntComparisonConverter::__getMaxValue(std::string op)
+{
+       return __map[op].back();
+}
+
+int IntComparisonConverter::__getMinValue(std::string op)
+{
+       return __map[op].front();
+}
+
+bool IntComparisonConverter::__checkEtc()
+{
+       // Simple version in, notIn
+       IF_FAIL_RETURN(!__checkIn(), true);
+       IF_FAIL_RETURN(!__checkNotIn(), true);
+
+       return false;
+}
+
+
+bool IntComparisonConverter::__checkIn()
+{
+       // And of { >= min, <= max }
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
+       IF_FAIL_RETURN(__size == 2, false);
+       IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO) == 1
+                       && __getOperatorCount(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) == 1, false);
+
+       int maxOfGE = __getMaxValue(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO);
+       int minOfLE = __getMinValue(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO);
+       IF_FAIL_RETURN(maxOfGE <= minOfLE, false);
+
+       __setConvertedOperator(TRIG_RULE_OP_IN);
+       __setComparisonValue(maxOfGE, minOfLE);
+
+       return true;
+}
+
+bool IntComparisonConverter::__checkNotIn()
+{
+       // Or of { < min, > max }
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
+       IF_FAIL_RETURN(__size == 2, false);
+       IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN) == 1
+                       && __getOperatorCount(TRIG_RULE_OP_LESS_THAN) == 1, false);
+
+       int maxOfL = __getMaxValue(TRIG_RULE_OP_LESS_THAN);
+       int minOfG = __getMinValue(TRIG_RULE_OP_GREATER_THAN);
+       IF_FAIL_RETURN(maxOfL <= minOfG, false);
+
+       __setConvertedOperator(TRIG_RULE_OP_NOT_IN);
+       __setComparisonValue(maxOfL, minOfG);
+
+       return true;
+}
+
+void IntComparisonConverter::__setComparisonValue(int val1, int val2)
+{
+       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val1);
+       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val2);
+}
+
diff --git a/src/trigger/IntComparisonConverter.h b/src/trigger/IntComparisonConverter.h
new file mode 100644 (file)
index 0000000..f18cd2b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_INT_COMPARISON_CONVERTER_H_
+#define _CONTEXT_INT_COMPARISON_CONVERTER_H_
+
+#include <list>
+#include <CtxJson1.h>
+#include "ComparisonConverter.h"
+
+namespace ctx {
+
+       class IntComparisonConverter : public ComparisonConverter {
+               typedef std::list<int> IntList;         // Integer value list
+               typedef std::map<std::string, IntList> IntComparisonMap;                // { operator, IntList }
+
+       public:
+               IntComparisonConverter(CtxJson1 info);
+               ~IntComparisonConverter() {};
+
+       private:
+               IntComparisonMap __map;
+
+               void __insertComparisonInfo(std::string op, int val);
+               void __sort();
+               int __getMaxValue(std::string op);
+               int __getMinValue(std::string op);
+
+               bool __checkIn();
+               bool __checkNotIn();
+               void __setComparisonValue(int val1, int val2);
+               /* From CompariconConverter */
+               int __getOperatorCount(std::string op);
+               bool __checkEtc();
+       };
+
+}      /* namespace ctx */
+
+#endif /* _CONTEXT_INT_COMPARISON_CONVERTER_H_ */
diff --git a/src/trigger/StringComparisonConverter.cpp b/src/trigger/StringComparisonConverter.cpp
new file mode 100644 (file)
index 0000000..f4c1757
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "StringComparisonConverter.h"
+
+using namespace ctx;
+
+StringComparisonConverter::StringComparisonConverter(CtxJson1 info) :
+       ComparisonConverter(TRIG_TMPL_TYPE_STRING, info)
+{
+       if (__size >= 2) {
+               for (int i = 0; i < __size; i++) {
+                       std::string op;
+                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
+
+                       __map[op]++;
+               }
+       }
+
+       __convertComparison();
+}
+
+
+int StringComparisonConverter::__getOperatorCount(std::string op)
+{
+       return __map[op];
+}
+
diff --git a/src/trigger/StringComparisonConverter.h b/src/trigger/StringComparisonConverter.h
new file mode 100644 (file)
index 0000000..69fb110
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_STRING_COMPARISON_CONVERTER_H_
+#define _CONTEXT_STRING_COMPARISON_CONVERTER_H_
+
+#include <map>
+#include <CtxJson1.h>
+#include "ComparisonConverter.h"
+
+namespace ctx {
+
+       class StringComparisonConverter : public ComparisonConverter {
+               typedef std::map<std::string, int> StringComparisonMap;
+
+       public:
+               StringComparisonConverter(CtxJson1 info);
+               ~StringComparisonConverter() {};
+
+       private:
+               StringComparisonMap __map;
+
+               /* From CompariconConverter */
+               int __getOperatorCount(std::string op);
+       };
+
+}      /* namespace ctx */
+
+#endif /* _CONTEXT_STRING_COMPARISON_CONVERTER_H_ */
diff --git a/src/trigger/TriggerOldRuleTypes.h b/src/trigger/TriggerOldRuleTypes.h
new file mode 100644 (file)
index 0000000..fe85d67
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
+#define _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
+
+/* Old Rule Keys */
+#define OLD_TRIG_RULE_KEY_EVENT "EVENT"
+#define OLD_TRIG_RULE_KEY_EVENT_ITEM "ITEM_NAME"
+#define OLD_TRIG_RULE_KEY_EVENT_OPERATOR "ITEM_OPERATOR"
+#define OLD_TRIG_RULE_KEY_EVENT_OPTION "OPTION"
+#define OLD_TRIG_RULE_KEY_OPERATOR "OPERATOR"
+#define OLD_TRIG_RULE_KEY_CONDITION "CONDITION"
+#define OLD_TRIG_RULE_KEY_CONDITION_ITEM "ITEM_NAME"
+#define OLD_TRIG_RULE_KEY_CONDITION_OPERATOR "ITEM_OPERATOR"
+#define OLD_TRIG_RULE_KEY_CONDITION_OPTION "OPTION"
+#define OLD_TRIG_RULE_KEY_DATA_ARR "DATA_ARR"
+#define OLD_TRIG_RULE_KEY_DATA_KEY "DATA_KEY"
+#define OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR "DATA_KEY_OPERATOR"
+#define OLD_TRIG_RULE_KEY_DATA_VALUE_ARR "DATA_VALUE_ARR"
+#define OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR "DATA_VALUE_OPER_ARR"
+
+#endif /* _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_ */
diff --git a/src/trigger/context_trigger.cpp b/src/trigger/context_trigger.cpp
new file mode 100644 (file)
index 0000000..de50622
--- /dev/null
@@ -0,0 +1,1206 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#include <sstream>
+//#include <iomanip>
+#include <app_control_internal.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <pkgmgr-info.h>
+#include <context_trigger.h>
+#include <context_trigger_internal.h>
+#include <Types.h>
+#include <DBusTypes.h>
+#include <CtxJson1.h>
+#include <DBusClient.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "TriggerOldRuleTypes.h"
+#include "rule_validator.h"
+#include "rule_util.h"
+
+#define TRIGGER_DEPRECATED_FUNCTION_MSG "DEPRECATION WARNING: %s is deprecated and will be removed from next release."
+#define TRIGGER_DEPRECATED_EVENT_MSG "DEPRECATION WARNING: This event is deprecated and will be removed from next release."
+#define TRIGGER_DEPRECATED_CONDITION_MSG "DEPRECATION WARNING: This condition is deprecated and will be removed from next release."
+
+//#define DOUBLE_PRECISION 2
+#define TYPE_EVENT 1
+#define TYPE_CONDITION 2
+#define TYPE_OPTION TRIG_TMPL_KEY_OPTION
+#define TYPE_ATTRIBUTE TRIG_TMPL_KEY_ATTRIBUTE
+#define OLD_INITIAL_ENTRY "{ \"" OLD_TRIG_RULE_KEY_DATA_ARR "\" : [ ] }"
+#define INITIAL_REF "{ \"" TRIG_TMPL_KEY_OPTION "\" : [ ], \"" TRIG_TMPL_KEY_ATTRIBUTE "\" : [ ] }"
+#define INITIAL_RULE \
+"{ \"" TRIG_RULE_KEY_DESCRIPTION "\" : \"\", \"" TRIG_RULE_KEY_EVENT "\" : { }, \"" TRIG_RULE_KEY_CONDITION "\" : [ ], \"" \
+TRIG_RULE_KEY_ACTION "\" : { }, \"" _TRIG_RULE_KEY_EXTRA "\": { } }"
+#define INITIAL_ENTRY "{ \"" TRIG_RULE_KEY_OPTION "\": { }, \"" TRIG_RULE_KEY_COMPARISON "\" : { } }"
+
+static ctx::DBusClient __dbusClient;
+
+static int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
+static int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom = false);
+static std::string convert_event_to_string(context_trigger_event_e item);
+static std::string convert_condition_to_string(context_trigger_condition_e item);
+static std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type);
+static std::string get_custom_item_subject(const char* provider, const char* item);
+static bool event_is_deprecated(context_trigger_event_e item);
+static bool condition_is_deprecated(context_trigger_condition_e item);
+
+//static std::string int_to_string(int value);
+//static std::string double_to_string(int value);
+
+typedef struct _context_trigger_rule_s {
+       ctx::CtxJson1 jold_rule;
+       ctx::CtxJson1 jrule;    // description, event{}, condition[], action{}, _extra{}
+       ctx::CtxJson1 jref;
+
+       _context_trigger_rule_s() {
+               jold_rule = EMPTY_JSON_OBJECT;
+               jrule = INITIAL_RULE;
+               jref = INITIAL_REF;
+       }
+} _context_trigger_rule_h;
+
+typedef struct _context_trigger_rule_entry_s {
+       int type;
+       ctx::CtxJson1 jentry;
+       ctx::CtxJson1 jref;
+
+       _context_trigger_rule_entry_s(int t): type(t) {
+               jentry = OLD_INITIAL_ENTRY;
+
+               if (t == TYPE_CONDITION) {
+                       jref = INITIAL_REF;
+               }
+       }
+} _context_trigger_rule_entry_h;
+
+// Add a rule
+SO_EXPORT int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule && rule_id);
+
+       // Err: No event
+       if (!ctx::rule_util::isEventSet(rule->jrule)) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       // Err: No action
+       if (!ctx::rule_util::isActionSet(rule->jrule)) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       // If condition size isn't greater than 1, update logical operator as default
+       if ((rule->jrule).getSize(NULL, TRIG_RULE_KEY_CONDITION) <= 1) {
+               (rule->jrule).set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, TRIG_RULE_LOGICAL_CONJUNCTION);
+       }
+
+       ctx::CtxJson1 jrule_id;
+       int error = __dbusClient.write(SUBJ_TRIGGER_ADD, rule->jrule, &jrule_id);
+
+       if (error == ERR_NONE) {
+               jrule_id.get(NULL, TRIG_KEY_RULE_ID, rule_id);
+       }
+
+       return error;
+}
+
+// Remove a rule
+SO_EXPORT int context_trigger_remove_rule(int rule_id)
+{
+       _D("BEGIN");
+       if (rule_id <= 0)
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+       ctx::CtxJson1 jrule_id;
+       jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+       int error = __dbusClient.write(SUBJ_TRIGGER_REMOVE, jrule_id, NULL);
+
+       if (error == ERR_ALREADY_STARTED) {     // Rule is still enabled.
+               return CONTEXT_TRIGGER_ERROR_RULE_ENABLED;
+       } else if (error == ERR_NO_DATA) {
+               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+       }
+
+       return error;
+}
+
+// Enable a rule
+SO_EXPORT int context_trigger_enable_rule(int rule_id)
+{
+       _D("BEGIN");
+       if (rule_id <= 0)
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+       ctx::CtxJson1 jrule_id;
+       jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+
+       int req_id;     // Useless in context_trigger
+       int error = __dbusClient.subscribe(SUBJ_TRIGGER_ENABLE, jrule_id, &req_id, NULL);
+
+       if (error == ERR_NO_DATA) {
+               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+       }
+
+       return error;
+}
+
+// Disable a rule
+SO_EXPORT int context_trigger_disable_rule(int rule_id)
+{
+       _D("BEGIN");
+       if (rule_id <= 0)
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+       ctx::CtxJson1 jrule_id;
+       jrule_id.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+       int error = __dbusClient.write(SUBJ_TRIGGER_DISABLE, jrule_id, NULL);
+
+       if (error == ERR_NO_DATA) {
+               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+       }
+
+       return error;
+}
+
+SO_EXPORT int context_trigger_get_own_rule_ids(int** enabled_rule_ids, int* enabled_rule_count, int** disabled_rule_ids, int* disabled_rule_count)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(enabled_rule_ids && enabled_rule_count && disabled_rule_ids && disabled_rule_count);
+
+       int req_id;
+       ctx::CtxJson1 data_read;
+       int error = __dbusClient.readSync(SUBJ_TRIGGER_GET_RULE_IDS, NULL, &req_id, &data_read);
+
+       if (error != ERR_NONE) {
+               return error;
+       }
+
+       // Enabled rules
+       int* e_arr = NULL;
+       *enabled_rule_count = data_read.getSize(NULL, TRIG_KEY_ENABLED_IDS);
+
+       if (*enabled_rule_count > 0) {
+               e_arr = static_cast<int*>(g_malloc((*enabled_rule_count) * sizeof(int)));
+               IF_FAIL_RETURN_TAG(e_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+               int id;
+               for (int i = 0; data_read.getAt(NULL, TRIG_KEY_ENABLED_IDS, i, &id); i++) {
+                       *(e_arr + i) = id;
+               }
+       }
+       *enabled_rule_ids = e_arr;
+
+       // Disabled rules
+       int* d_arr = NULL;
+       *disabled_rule_count = data_read.getSize(NULL, TRIG_KEY_DISABLED_IDS);
+
+       if (*disabled_rule_count > 0) {
+               d_arr = static_cast<int*>(g_malloc((*disabled_rule_count) * sizeof(int)));
+               IF_FAIL_RETURN_TAG(d_arr, CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+               int id;
+               for (int i = 0; data_read.getAt(NULL, TRIG_KEY_DISABLED_IDS, i, &id); i++) {
+                       *(d_arr + i) = id;
+               }
+       }
+       *disabled_rule_ids = d_arr;
+
+       return error;
+}
+
+
+SO_EXPORT int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule);
+       if (rule_id <= 0)
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+
+       ctx::CtxJson1 option;
+       option.set(NULL, TRIG_KEY_RULE_ID, rule_id);
+
+       int req_id;
+       ctx::CtxJson1 data_read;
+       int error = __dbusClient.readSync(SUBJ_TRIGGER_GET, option, &req_id, &data_read);
+
+       if (error == ERR_NO_DATA) {
+               return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
+       } else if (error != ERR_NONE) {
+               return error;
+       }
+
+       *rule = new(std::nothrow) _context_trigger_rule_h();
+       (*rule)->jrule = data_read;
+
+       return ERR_NONE;
+}
+
+// Rule creation
+SO_EXPORT int context_trigger_rule_create(context_trigger_logical_type_e logical_type, context_trigger_rule_h* rule)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule);
+
+       std::string logical_str = convert_logical_type_to_string(logical_type);
+       if (logical_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       *rule = new(std::nothrow) _context_trigger_rule_h();
+       (*rule)->jold_rule.set(NULL, OLD_TRIG_RULE_KEY_OPERATOR, logical_str);
+
+       (*rule)->jrule.set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, logical_str);
+
+       return ERR_NONE;
+}
+
+// Rule deletion
+SO_EXPORT int context_trigger_rule_destroy(context_trigger_rule_h rule)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule);
+       delete rule;
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+
+SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule && entry);
+
+       // Check if rule handle is created
+       ctx::CtxJson1 extra;
+       bool ret = (rule->jrule).get(NULL, _TRIG_RULE_KEY_EXTRA, &extra);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER);
+
+       if (entry->type == TYPE_EVENT) {
+               // Err: More than one event
+               ctx::CtxJson1 elem;
+               if ((rule->jold_rule).get(NULL, OLD_TRIG_RULE_KEY_EVENT, &elem)) {
+                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+               }
+
+               // Err: Check if all the mandatory options are added
+               ret = ctx::rule_validator::check_option(entry->jentry);
+               IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+               // Err: If referential conditions are registered priviously, check them
+               std::string ename;
+               (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
+               ret = ctx::rule_validator::check_referential_data(ename, rule->jref);
+               IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+               ctx::CtxJson1 temp = (entry->jentry).str();
+               ret = (rule->jold_rule).set(NULL, OLD_TRIG_RULE_KEY_EVENT, temp);
+
+               int error = ctx::rule_util::setEvent(entry->jentry, &(rule->jrule));
+               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add event entry");
+       } else if (entry->type == TYPE_CONDITION) {
+               // Err: Condition without comparison data
+               if ((entry->jentry).getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) < 1) {
+                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+               }
+
+               ctx::CtxJson1 elem;
+               for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+                       int val_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
+                       int op_arr_size = elem.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR);
+
+                       // Err: Condition without comparison data
+                       if (val_arr_size != op_arr_size || val_arr_size < 1 || op_arr_size < 1) {
+                               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+                       }
+
+                       // Err: Check if all the mandatory options are added
+                       ret = ctx::rule_validator::check_option(entry->jentry);
+                       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+                       // If event is already added ....
+                       std::string ename;
+                       ret = (rule->jold_rule).get(OLD_TRIG_RULE_KEY_EVENT, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
+                       if (ret) {
+                               // Err: Check referential information if exists
+                               ret = ctx::rule_validator::check_referential_data(ename, entry->jref);
+                               IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+                       } else {
+                               // If not, copy referential information to rule entry
+                               ctx::CtxJson1 info;
+                               for (int j = 0; (entry->jref).getAt(NULL, TYPE_OPTION, j, &info); j++) {
+                                       (rule->jref).append(NULL, TYPE_OPTION, info);
+                               }
+
+                               for (int j = 0; (entry->jref).getAt(NULL, TYPE_ATTRIBUTE, j, &info); j++) {
+                                       (rule->jref).append(NULL, TYPE_ATTRIBUTE, info);
+                               }
+                       }
+               }
+
+               ctx::CtxJson1 temp = (entry->jentry).str();
+               ret = (rule->jold_rule).append(NULL, OLD_TRIG_RULE_KEY_CONDITION, temp);
+
+               ctx::rule_util::addCondition(entry->jentry, &(rule->jrule));
+       } else {
+               // Entry is not created
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+static bool is_call_operation(app_control_h app_control)
+{
+       char *op = NULL;
+       int err = app_control_get_operation(app_control, &op);
+       IF_FAIL_RETURN_TAG(err == APP_CONTROL_ERROR_NONE, false, _W, "Getting operation of app control failed");
+
+       bool ret = STR_EQ(op, APP_CONTROL_OPERATION_CALL);
+       g_free(op);
+
+       return ret;
+}
+
+SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule && app_control);
+       int error;
+
+       // Privilege check
+       error = __dbusClient.call(METHOD_CHK_PRIV_APPLAUNCH);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+
+       if (is_call_operation(app_control)) {
+               error = __dbusClient.call(METHOD_CHK_PRIV_CALL);
+               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+       }
+
+       // Err: if action arleady exists
+       if (ctx::rule_util::isActionSet(rule->jrule)) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       // Err: service app
+       char* app_id = NULL;
+       error = app_control_get_app_id(app_control, &app_id);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
+
+       pkgmgrinfo_appinfo_h app_info;
+       error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
+       g_free(app_id);
+       IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
+
+       // Service apps are not allowed to be launched (Mobile & Wearable)
+       char *app_type = NULL;
+       pkgmgrinfo_appinfo_get_component_type(app_info, &app_type);
+       if (!strcmp(app_type, "svcapp")) {
+               _E("Service application is restricted");
+               pkgmgrinfo_appinfo_destroy_appinfo(app_info);
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+       pkgmgrinfo_appinfo_destroy_appinfo(app_info);
+
+       // Set app control
+       bundle* appctl_bundle = NULL;
+       error = app_control_to_bundle(app_control, &appctl_bundle);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
+
+       bundle_raw* appctl_raw;
+       int raw_length;
+       error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
+
+       std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_APP_LAUNCH, TRIG_RULE_KEY_APP_LAUNCH_APP_CONTROL, appctl_str);
+       bundle_free_encoded_rawdata(&appctl_raw);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_set_action_notification(context_trigger_rule_h rule, const char* title, const char* content, const char* icon_path, app_control_h app_control)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule && title && content);
+
+       // Privilege check
+       int error = __dbusClient.call(METHOD_CHK_PRIV_NOTIFICATION);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+
+       // if action arleady exists
+       if (ctx::rule_util::isActionSet(rule->jrule)) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       // Err: App control check
+       if (app_control) {
+               char* app_id = NULL;
+               error = app_control_get_app_id(app_control, &app_id);
+               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get app id");
+
+               pkgmgrinfo_appinfo_h app_info;
+               error = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &app_info);
+               g_free(app_id);
+               IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_RULE, _E, "No such app");
+
+               pkgmgrinfo_appinfo_destroy_appinfo(app_info);
+       }
+
+       // Set title, content
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_TITLE, title);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_CONTENT, content);
+
+       // Set icon path
+       if (icon_path) {
+               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_ICON_PATH, icon_path);
+       }
+
+       // Set app control
+       if (app_control) {
+               bundle* appctl_bundle = NULL;
+               error = app_control_to_bundle(app_control, &appctl_bundle);
+               IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "App_control to bundle failed");
+
+               bundle_raw* appctl_raw;
+               int raw_length;
+               error = bundle_encode(appctl_bundle, &appctl_raw, &raw_length);
+               IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
+
+               std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
+               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_APP_CONTROL, appctl_str);
+
+               bundle_free_encoded_rawdata(&appctl_raw);
+       }
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+//LCOV_EXCL_START
+SO_EXPORT int context_trigger_rule_set_action_dbus_call(context_trigger_rule_h rule,
+               const char *bus_name, const char *object_path, const char *interface_name, const char *method_name, GVariant *param)
+{
+       ASSERT_NOT_NULL(rule && bus_name && object_path && interface_name && method_name);
+
+       /* if action arleady exists */
+       if (ctx::rule_util::isActionSet(rule->jrule)) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       /* Set basic dbus method call info */
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_NAME, bus_name);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_OBJECT, object_path);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_INTERFACE, interface_name);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_METHOD, method_name);
+
+       /* Set the parameters */
+       if (param)
+               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_PARAMETER, param);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
+
+// Set description
+SO_EXPORT int context_trigger_rule_set_description(context_trigger_rule_h rule, const char* description)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule);
+
+       (rule->jrule).set(NULL, TRIG_RULE_KEY_DESCRIPTION, description);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Get rule description
+SO_EXPORT int context_trigger_rule_get_description(context_trigger_rule_h rule, char** description)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(rule && description);
+
+       std::string val;
+       (rule->jrule).get(NULL, TRIG_RULE_KEY_DESCRIPTION, &val);
+
+       *description = strdup(val.c_str());
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Event creation
+SO_EXPORT int context_trigger_rule_event_create(context_trigger_event_e event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry);
+
+       if (event_is_deprecated(event_item)) {
+               _W(TRIGGER_DEPRECATED_EVENT_MSG);
+       }
+
+       std::string eitem_str = convert_event_to_string(event_item);
+       if (eitem_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       int error = context_trigger_rule_event_create_internal(eitem_str.c_str(), logical_type, entry);
+       return error;
+}
+
+SO_EXPORT int context_trigger_rule_custom_event_create(const char* event_item, const char* provider, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(event_item && provider && entry);
+
+       // Err: Invalid provider
+       pkgmgrinfo_pkginfo_h pkg_info;
+       int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+       IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
+
+       std::string subject = get_custom_item_subject(provider, event_item);
+       error = context_trigger_rule_event_create_internal(subject.c_str(), logical_type, entry, true);
+
+       return error;
+}
+
+int context_trigger_rule_event_create_internal(const char* event_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(event_item);
+
+       // Err: Invalid logical operator
+       std::string logical_str = convert_logical_type_to_string(logical_type);
+       if (logical_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       int error = ctx::rule_validator::request_template(event_item, is_custom);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
+
+       *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_EVENT);
+       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, event_item);
+       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, logical_str);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Event availability check
+SO_EXPORT int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(supported);
+
+       if (event_is_deprecated(event_item)) {
+               _W(TRIGGER_DEPRECATED_EVENT_MSG);
+       }
+
+       *supported = false;
+
+       std::string eitem_str = convert_event_to_string(event_item);
+       if (eitem_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       int error = __dbusClient.isSupported(eitem_str);
+
+       if (error == ERR_NONE)
+               *supported = true;
+
+       if (error == ERR_NOT_SUPPORTED)
+               return ERR_NONE;
+
+       return error;
+}
+
+// Condition creation
+SO_EXPORT int context_trigger_rule_condition_create(context_trigger_condition_e condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry);
+
+       if (condition_is_deprecated(condition_item)) {
+               _W(TRIGGER_DEPRECATED_CONDITION_MSG);
+       }
+
+       std::string citem_str = convert_condition_to_string(condition_item);
+       if (citem_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       int error = context_trigger_rule_condition_create_internal(citem_str.c_str(), logical_type, entry);
+       return error;
+}
+
+SO_EXPORT int context_trigger_rule_custom_condition_create(const char* condition_item, const char* provider, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(condition_item && provider && entry);
+
+       // Err: Invalid provider
+       pkgmgrinfo_pkginfo_h pkg_info;
+       int error = pkgmgrinfo_pkginfo_get_usr_pkginfo(provider, getuid(), &pkg_info);
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+       IF_FAIL_RETURN_TAG(error == PMINFO_R_OK, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
+
+       std::string subject = get_custom_item_subject(provider, condition_item);
+       error = context_trigger_rule_condition_create_internal(subject.c_str(), logical_type, entry, true);
+       return error;
+}
+
+int context_trigger_rule_condition_create_internal(const char* condition_item, context_trigger_logical_type_e logical_type, context_trigger_rule_entry_h* entry, bool is_custom)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(condition_item);
+
+       std::string logical_str = convert_logical_type_to_string(logical_type);
+       if (logical_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       int error = ctx::rule_validator::request_template(condition_item, is_custom);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
+
+       *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_CONDITION);
+       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, condition_item);
+       (*entry)->jentry.set(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, logical_str);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+// Condition availability check
+SO_EXPORT int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(supported);
+
+       if (condition_is_deprecated(condition_item)) {
+               _W(TRIGGER_DEPRECATED_CONDITION_MSG);
+       }
+
+       *supported = false;
+
+       std::string citem_str = convert_condition_to_string(condition_item);
+       if (citem_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       int error = __dbusClient.isSupported(citem_str);
+
+       if (error == ERR_NONE)
+               *supported = true;
+
+       if (error == ERR_NOT_SUPPORTED)
+               return ERR_NONE;
+
+       return error;
+}
+
+// Rule data deletion
+SO_EXPORT int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry);
+       delete entry;
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_option_int(context_trigger_rule_entry_h entry, const char* option_key, int value)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry && option_key);
+
+       bool ret = true;
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+       ret = ctx::rule_validator::check_option_int(name, option_key, value);
+       if (!ret) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_option_string(context_trigger_rule_entry_h entry, const char* option_key, const char* value)
+{
+       _D("BEGIN");
+       _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
+       ASSERT_NOT_NULL(entry && option_key && value);
+
+       bool ret = true;
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+       ret = ctx::rule_validator::check_option_string(name, option_key, value);
+       if (!ret) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h entry, const char* option_key, const char* event_data_key)
+{
+       _D("BEGIN");
+       _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
+       ASSERT_NOT_NULL(entry && option_key && event_data_key);
+
+       // Err: Only conditin can reference data from event
+       if (entry->type != TYPE_CONDITION) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+
+       // Err: Check if key is valid
+       bool ret = ctx::rule_validator::check_valid_key(TYPE_OPTION, name, option_key);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+       // Set reference information
+       ret = ctx::rule_validator::set_ref_info(TYPE_OPTION, &(entry->jref), name, option_key, event_data_key);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
+
+       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_key(context_trigger_rule_entry_h entry, context_trigger_logical_type_e logical_type, const char* key)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry && key);
+
+       std::string logical_str = convert_logical_type_to_string(logical_type);
+       if (logical_str.empty()) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       // Err: Check if key is valid
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+       // Err: Comparison key is already added
+       ctx::CtxJson1 elem;
+       for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+               std::string elem_item;
+               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
+               // Err: Comparison key is already added
+               if (elem_item.compare(key) == 0) {
+                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+               }
+       }
+
+       ctx::CtxJson1 data;
+       data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, key);
+       data.set(NULL, OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR, logical_str);
+       (entry->jentry).append(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, data);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+static int context_trigger_rule_entry_add_comparison_string_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, std::string value)
+{
+       ctx::CtxJson1 elem;
+       for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+               std::string elem_item;
+               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
+
+               if (elem_item.compare(key) == 0) {
+                       std::string elem_val;
+                       std::string elem_op;
+                       for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
+                               elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
+
+                               // Err: Duplicated <operator, value>
+                               if (elem_val.compare(value) == 0 && elem_op.compare(op) == 0) {
+                                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+                               }
+                       }
+                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value.c_str());
+                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
+                       (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
+
+                       return CONTEXT_TRIGGER_ERROR_NONE;
+               }
+       }
+
+       // Comparison key not exist
+       return CONTEXT_TRIGGER_ERROR_NO_DATA;
+}
+
+static int context_trigger_rule_entry_add_comparison_int_internal(context_trigger_rule_entry_h entry, const char* key, std::string op, int value)
+{
+       ctx::CtxJson1 elem;
+       for (int i = 0; (entry->jentry).getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+               std::string elem_item;
+               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &elem_item);
+
+               if (elem_item.compare(key) == 0) {
+                       int elem_val;
+                       std::string elem_op;
+                       for (int j = 0; elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, j, &elem_val); j++) {
+                               elem.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, j, &elem_op);
+
+                               // Err: Duplicated <operator, value>
+                               if (elem_val == value && elem_op.compare(op) == 0) {
+                                       return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+                               }
+                       }
+                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, value);
+                       elem.append(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, op);
+                       (entry->jentry).setAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, elem);
+
+                       return CONTEXT_TRIGGER_ERROR_NONE;
+               }
+       }
+
+       // Comparison key not exist
+       return CONTEXT_TRIGGER_ERROR_NO_DATA;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* event_data_key)
+{
+       _D("BEGIN");
+       _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
+       ASSERT_NOT_NULL(entry && key && op && event_data_key);
+
+       // Err: Only condition can reference data from event
+       if (entry->type != TYPE_CONDITION) {
+               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+
+       // Err: Check if key is valid
+       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTRIBUTE, name, key);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+       // Err: Invalid operator
+       std::string type = ctx::rule_validator::get_data_type_from_template(TYPE_ATTRIBUTE, name, key);
+       ret = ctx::rule_validator::is_valid_operator(type, op);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+       int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
+       IF_FAIL_RETURN(error == ERR_NONE, error);
+
+       // Set reference information
+       ret = ctx::rule_validator::set_ref_info(TYPE_ATTRIBUTE, &(entry->jref), name, key, event_data_key);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+SO_EXPORT int context_trigger_rule_entry_add_comparison_int(context_trigger_rule_entry_h entry, const char* key, const char* op, int value)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry && key && op);
+
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+       bool ret = ctx::rule_validator::check_comparison_int(name, key, op, value);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+       int error = context_trigger_rule_entry_add_comparison_int_internal(entry, key, op, value);
+       return error;
+}
+/*
+SO_EXPORT int context_trigger_rule_entry_add_comparison_double(context_trigger_rule_entry_h entry, const char* key, const char* op, double value)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry && key && op);
+
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+       // TODO: check_comparison_double()
+       bool ret = ctx::rule_validator::check_comparison_double(name, key, op, value);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+       int error = context_trigger_rule_entry_add_comparison_internal(entry, key, op, double_to_string(value));
+       return error;
+}
+*/
+SO_EXPORT int context_trigger_rule_entry_add_comparison_string(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* value)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(entry && key && op && value);
+
+       std::string name;
+       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+       bool ret = ctx::rule_validator::check_comparison_string(name, key, op, value);
+       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+
+       int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, value);
+       return error;
+}
+
+SO_EXPORT int context_trigger_custom_register(const char* name, const char* attr_template)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(name && attr_template);
+
+       // Err: Invalid CtxJson1
+       ctx::CtxJson1 jattr_template = attr_template;
+       IF_FAIL_RETURN_TAG(jattr_template.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Failed to parse template");
+
+       // Err: Invalid template
+       bool ret = ctx::rule_validator::is_valid_template(jattr_template);
+       IF_FAIL_RETURN_TAG(ret, CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid template");
+
+       ctx::CtxJson1 data;
+       data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_ADD);
+       data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
+       data.set(NULL, TRIG_TMPL_KEY_ATTRIBUTE, jattr_template);
+
+       int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add custom item: %#x", error);
+
+       return error;
+}
+
+SO_EXPORT int context_trigger_custom_unregister(const char* name)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(name);
+
+       ctx::CtxJson1 data;
+       data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_REMOVE);
+       data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
+
+       ctx::CtxJson1 subj;
+       int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, &subj);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to remove custom item: %#x", error);
+
+       std::string subject;
+       subj.get(NULL, TRIG_TMPL_KEY_SUBJECT, &subject);
+       ctx::rule_validator::remove_template(subject);
+
+       return error;
+}
+
+SO_EXPORT int context_trigger_custom_publish(const char* name, const char* fact)
+{
+       _D("BEGIN");
+       ASSERT_NOT_NULL(name && fact);
+
+       // Err: Invalid CtxJson1
+       ctx::CtxJson1 jfact = fact;
+       IF_FAIL_RETURN_TAG(jfact.valid(), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Cannot parse fact CtxJson1");
+
+       ctx::CtxJson1 data;
+       data.set(NULL, TRIG_CUSTOM_KEY_REQ, TRIG_CUSTOM_REQ_PUBLISH);
+       data.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
+       data.set(NULL, TRIG_CUSTOM_KEY_FACT, jfact);
+
+       int error = __dbusClient.write(SUBJ_TRIGGER_CUSTOM, data, NULL);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to publish custom data");
+
+       return error;
+}
+
+std::string convert_event_to_string(context_trigger_event_e item)
+{
+       std::string str;
+       switch (item) {
+       case CONTEXT_TRIGGER_EVENT_TIME:
+               str = SUBJ_STATE_ALARM;
+               break;
+       case CONTEXT_TRIGGER_EVENT_BATTERY:
+               str = SUBJ_STATE_BATTERY;
+               break;
+       case CONTEXT_TRIGGER_EVENT_CHARGER:
+               str = SUBJ_STATE_CHARGER;
+               break;
+       case CONTEXT_TRIGGER_EVENT_GPS:
+               str = SUBJ_STATE_GPS;
+               break;
+       case CONTEXT_TRIGGER_EVENT_HEADPHONE:
+               str = SUBJ_STATE_HEADPHONE;
+               break;
+       case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
+               str = SUBJ_STATE_PSMODE;
+               break;
+       case CONTEXT_TRIGGER_EVENT_USB:
+               str = SUBJ_STATE_USB;
+               break;
+       case CONTEXT_TRIGGER_EVENT_WIFI:
+               str = SUBJ_STATE_WIFI;
+               break;
+       case CONTEXT_TRIGGER_EVENT_CALL:
+               str = SUBJ_STATE_CALL;
+               break;
+       case CONTEXT_TRIGGER_EVENT_EMAIL:
+               str = SUBJ_STATE_EMAIL;
+               break;
+       case CONTEXT_TRIGGER_EVENT_MESSAGE:
+               str = SUBJ_STATE_MESSAGE;
+               break;
+       case CONTEXT_TRIGGER_EVENT_CONTACTS:
+               str = SUBJ_STATE_CONTACTS;
+               break;
+       case CONTEXT_TRIGGER_EVENT_ACTIVITY_STATIONARY:
+               str = SUBJ_ACTIVITY_STATIONARY;
+               break;
+       case CONTEXT_TRIGGER_EVENT_ACTIVITY_WALKING:
+               str = SUBJ_ACTIVITY_WALKING;
+               break;
+       case CONTEXT_TRIGGER_EVENT_ACTIVITY_RUNNING:
+               str = SUBJ_ACTIVITY_RUNNING;
+               break;
+       case CONTEXT_TRIGGER_EVENT_ACTIVITY_IN_VEHICLE:
+               str = SUBJ_ACTIVITY_IN_VEHICLE;
+               break;
+       case CONTEXT_TRIGGER_EVENT_PLACE:
+               str = SUBJ_PLACE_GEOFENCE;
+               break;
+       default:
+               break;
+       }
+       return str;
+}
+
+std::string convert_condition_to_string(context_trigger_condition_e item)
+{
+       std::string str;
+       switch (item) {
+       case CONTEXT_TRIGGER_CONDITION_TIME:
+               str = SUBJ_STATE_TIME;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_BATTERY:
+               str = SUBJ_STATE_BATTERY;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_CHARGER:
+               str = SUBJ_STATE_CHARGER;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_GPS:
+               str = SUBJ_STATE_GPS;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_HEADPHONE:
+               str = SUBJ_STATE_HEADPHONE;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
+               str = SUBJ_STATE_PSMODE;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_USB:
+               str = SUBJ_STATE_USB;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_WIFI:
+               str = SUBJ_STATE_WIFI;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_CALL:
+               str = SUBJ_STATE_CALL;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
+               str = SUBJ_APP_FREQUENCY;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
+               str = SUBJ_SOCIAL_FREQUENCY;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
+               str = SUBJ_MUSIC_FREQUENCY;
+               break;
+       case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
+               str = SUBJ_VIDEO_FREQUENCY;
+               break;
+       default:
+               break;
+       }
+       return str;
+}
+
+std::string convert_logical_type_to_string(context_trigger_logical_type_e logical_type)
+{
+       std::string str;
+       switch (logical_type) {
+       case CONTEXT_TRIGGER_LOGICAL_CONJUNCTION:
+               str = TRIG_RULE_LOGICAL_CONJUNCTION;
+               break;
+       case CONTEXT_TRIGGER_LOGICAL_DISJUNCTION:
+               str = TRIG_RULE_LOGICAL_DISJUNCTION;
+               break;
+       default:
+               break;
+       }
+       return str;
+}
+
+std::string get_custom_item_subject(const char* provider, const char* item)
+{
+       std::string subject_name = std::string(TRIG_CUSTOM_PREFIX TRIG_SUBJECT_SEPERATOR) + provider + std::string(TRIG_SUBJECT_SEPERATOR) + item;
+       return subject_name;
+}
+
+bool event_is_deprecated(context_trigger_event_e item)
+{
+       bool ret = false;
+       switch (item) {
+       case CONTEXT_TRIGGER_EVENT_TIME:
+       case CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE:
+       case CONTEXT_TRIGGER_EVENT_CALL:
+       case CONTEXT_TRIGGER_EVENT_EMAIL:
+       case CONTEXT_TRIGGER_EVENT_MESSAGE:
+               ret = true;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
+bool condition_is_deprecated(context_trigger_condition_e item)
+{
+       bool ret = false;
+       switch (item) {
+       case CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE:
+       case CONTEXT_TRIGGER_CONDITION_CALL:
+       case CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY:
+       case CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY:
+       case CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY:
+       case CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY:
+               ret = true;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
+/*
+std::string int_to_string(int value)
+{
+       std::ostringstream ostr;
+       ostr << value;
+       return ostr.str();
+}
+
+std::string double_to_string(int value)
+{
+       std::ostringstream ostr;
+       ostr.imbue(std::locale("C"));
+       ostr << std::setprecision(DOUBLE_PRECISION) << std::fixed << value;
+       return ostr.str();
+}*/
diff --git a/src/trigger/rule_util.cpp b/src/trigger/rule_util.cpp
new file mode 100644 (file)
index 0000000..f57de01
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <map>
+#include <list>
+#include <context_trigger.h>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include <TimerManager.h>
+#include "rule_validator.h"
+#include "rule_util.h"
+#include "ComparisonConverter.h"
+#include "IntComparisonConverter.h"
+#include "StringComparisonConverter.h"
+
+using namespace ctx;
+
+static bool __handleTimerEvent(CtxJson1& event);
+static int __arrangeDayOfWeek(CtxJson1& dayInfo);
+
+int ctx::rule_util::setEvent(CtxJson1& entry, CtxJson1* rule)
+{
+       CtxJson1 tempEvent;
+       std::string subject;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &subject);
+
+       CtxJson1 option;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPTION, &option);
+       tempEvent.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
+
+       CtxJson1 elem;
+       for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+               CtxJson1 newElem;
+
+               std::string key;
+               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
+
+               std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
+
+               ComparisonConverter* converter = NULL;
+               if (type == TRIG_TMPL_TYPE_INTEGER) {
+                       converter = new(std::nothrow) IntComparisonConverter(elem);
+               } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
+                       converter = new(std::nothrow) StringComparisonConverter(elem);
+               }
+               IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
+               converter->getResult(&newElem);
+
+               CtxJson1 detail;
+               newElem.get(NULL, key.c_str(), &detail);
+
+               std::string path = subject + "." + TRIG_RULE_KEY_COMPARISON;
+               tempEvent.set(path.c_str(), key.c_str(), detail);
+               delete converter;
+       }
+
+       // Handle Timer Event
+       if (subject.compare(SUBJ_STATE_ALARM) == 0) {
+               IF_FAIL_RETURN(__handleTimerEvent(tempEvent), ERR_INVALID_RULE);
+       }
+
+       rule->set(NULL, TRIG_RULE_KEY_EVENT, tempEvent);
+
+       // Save event entry's logical to extra info (default and)
+       std::string eventOp = TRIG_RULE_LOGICAL_CONJUNCTION;
+       if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
+               entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, &eventOp);
+       }
+       rule->set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, eventOp);
+
+       return ERR_NONE;
+}
+
+int ctx::rule_util::addCondition(CtxJson1& entry, CtxJson1* rule)
+{
+       CtxJson1 tempCond;
+       std::string subject;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &subject);
+
+       CtxJson1 option;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPTION, &option);
+       tempCond.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
+
+       CtxJson1 elem;
+       for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+               CtxJson1 newElem;
+
+               std::string key;
+               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
+
+               std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
+
+               ComparisonConverter* converter = NULL;
+               if (type == TRIG_TMPL_TYPE_INTEGER) {
+                       converter = new(std::nothrow) IntComparisonConverter(elem);
+               } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
+                       converter = new(std::nothrow) StringComparisonConverter(elem);
+               }
+               IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
+               converter->getResult(&newElem);
+
+               tempCond.set(subject.c_str(), TRIG_RULE_KEY_COMPARISON, newElem);
+               delete converter;
+       }
+
+       rule->append(NULL, TRIG_RULE_KEY_CONDITION, tempCond);
+
+       // Save event entry's logical to extra info (default and)
+       std::string condOp = TRIG_RULE_LOGICAL_CONJUNCTION;
+       if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
+               entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, &condOp);
+       }
+       rule->append(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, condOp);
+
+       return ERR_NONE;
+}
+
+bool __handleTimerEvent(CtxJson1& event)
+{
+       CtxJson1 alarmComp;
+       bool ret = event.get(SUBJ_STATE_ALARM, TRIG_RULE_KEY_COMPARISON, &alarmComp);
+       IF_FAIL_RETURN_TAG(ret, false, _E, "Invalid EVENT_TIME event");
+
+       // Day processing
+       CtxJson1 dayInfo;
+       bool daySpecified = alarmComp.get(NULL, KEY_DAY_OF_WEEK, &dayInfo);
+
+       if (daySpecified) {
+               CtxJson1 newDayInfo;
+               newDayInfo.set(NULL, TRIG_RULE_KEY_OPERATOR, TRIG_RULE_OP_ONE_OF);
+
+               int dow = __arrangeDayOfWeek(dayInfo);
+               IF_FAIL_RETURN_TAG(dow > 0, false, _E, "Invalid DayOfWeek info for EVENT_TIME");
+
+               for (int i = 0 ; i < DAYS_PER_WEEK; i++) {
+                       int d = 0x01 << i;
+                       if (dow & d) {
+                               std::string day = TimerManager::dowToStr(d);
+                               newDayInfo.append(NULL, TRIG_RULE_KEY_VALUE, day);
+
+                               // Copy details as option
+                               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, day);
+                       }
+               }
+               event.set(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_COMPARISON, KEY_DAY_OF_WEEK, newDayInfo);
+       } else {
+               // If DayOfWeek is not specified, regard it as Mon ~ Sun
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_MON);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_TUE);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_WED);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_THU);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_FRI);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SAT);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SUN);
+       }
+
+       // Time processing
+       CtxJson1 timeInfo;
+       alarmComp.get(NULL, KEY_TIME_OF_DAY, &timeInfo);
+
+       int time;
+       std::string timeOp;
+       timeInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &timeOp);
+
+       if (timeOp == TRIG_RULE_OP_EQUAL_TO) {
+               timeInfo.get(NULL, TRIG_RULE_KEY_VALUE, &time);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
+       } else if (timeOp == TRIG_RULE_OP_ONE_OF) {
+               for (int i = 0; timeInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &time); i++) {
+                       event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
+               }
+       }
+
+       return true;
+}
+
+int __arrangeDayOfWeek(CtxJson1& dayInfo)
+{
+       std::string dayOp;
+       if (!dayInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &dayOp)) {
+               return TimerManager::dowToInt(DOW_EVERYDAY);
+       }
+
+       int result = 0;
+       if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO || dayOp == TRIG_RULE_OP_NOT_IN) {
+               result = TimerManager::dowToInt(DOW_EVERYDAY);
+       }
+
+       int dow;
+       std::string day;
+       if (dayOp == TRIG_RULE_OP_EQUAL_TO) {
+               dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
+               dow = TimerManager::dowToInt(day);
+               result |= dow;
+       } else if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO) {
+               dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
+               dow = TimerManager::dowToInt(day);
+               dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
+               result &= dow;
+       } else if (dayOp == TRIG_RULE_OP_ONE_OF) {
+               for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
+                       dow = TimerManager::dowToInt(day);
+                       result |= dow;
+               }
+       } else if (dayOp == TRIG_RULE_OP_NONE_OF) {
+               for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
+                       dow = TimerManager::dowToInt(day);
+                       dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
+                       result &= dow;
+               }
+       }
+
+       _D("Requested day of week (%#x)", result);
+       return result;
+}
+
+bool ctx::rule_util::isEventSet(CtxJson1& rule)
+{
+       ctx::CtxJson1 event;
+       if (rule.get(NULL, TRIG_RULE_KEY_EVENT, &event)) {
+               if (event != EMPTY_JSON_OBJECT) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+bool ctx::rule_util::isActionSet(CtxJson1& rule)
+{
+       ctx::CtxJson1 action;
+       if (rule.get(NULL, TRIG_RULE_KEY_ACTION, &action)) {
+               if (action != EMPTY_JSON_OBJECT) {
+                       return true;
+               }
+       }
+
+       return false;
+}
diff --git a/src/trigger/rule_util.h b/src/trigger/rule_util.h
new file mode 100644 (file)
index 0000000..d4443bb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_RULE_UTIL_H__
+#define __CONTEXT_RULE_UTIL_H__
+
+#include <CtxJson1.h>
+
+namespace ctx {
+
+       namespace rule_util {
+
+               int setEvent(CtxJson1& entry, CtxJson1* rule);
+               int addCondition(CtxJson1& entry, CtxJson1* rule);
+               bool isEventSet(CtxJson1& rule);
+               bool isActionSet(CtxJson1& rule);
+
+       }
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_RULE_UTIL_H__ */
diff --git a/src/trigger/rule_validator.cpp b/src/trigger/rule_validator.cpp
new file mode 100644 (file)
index 0000000..6f37448
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sstream>
+#include <string>
+#include <map>
+#include <Types.h>
+#include <context_trigger.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "DBusClient.h"
+#include "TriggerOldRuleTypes.h"
+#include "rule_validator.h"
+
+using namespace ctx;
+
+#define RULE_VALIDATOR_COND_NAME "name"
+#define RULE_VALIDATOR_KEY "key"
+#define RULE_VALIDATOR_TYPE "type"
+#define RULE_VALIDATOR_REF "ref"
+
+typedef std::map<std::string, CtxJson1> template_map_t;
+template_map_t template_map;   // <name, template>
+
+static int string_to_int(std::string str);
+static bool check_value_int(CtxJson1& tmpl, std::string key, int value);
+static bool check_value_string(CtxJson1& tmpl, std::string key, std::string value);
+static bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value);
+static CtxJson1 get_template(std::string name);
+static bool check_template_int(CtxJson1& elem);
+static bool check_template_string(CtxJson1& elem);
+static bool check_template_enum(CtxJson1& elem);
+static std::string get_data_type(CtxJson1& elem, std::string& key);
+static bool is_equal_type(std::string& type1, std::string& type2);
+
+int string_to_int(std::string str)
+{
+       int i;
+       std::istringstream convert(str);
+
+       if (!(convert >> i))
+               i = 0;
+
+       return i;
+}
+
+CtxJson1 get_template(std::string name)
+{
+       rule_validator::request_template(name);
+       return template_map[name];
+}
+
+int rule_validator::request_template(std::string name, bool mandatory)
+{
+       if (!mandatory) {
+               template_map_t::iterator it = template_map.find(name);
+               IF_FAIL_RETURN(it == template_map.end(), ERR_NONE);
+       }
+
+       // Request template
+       CtxJson1 request;
+       request.set(NULL, TRIG_TMPL_KEY_SUBJECT, name);
+
+       int req_id;
+       CtxJson1 tmpl;
+       DBusClient dbusClient;
+       int error = dbusClient.readSync(SUBJ_TRIGGER_GET_TEMPLATE, request, &req_id, &tmpl);
+       if (error == ERR_NOT_SUPPORTED) {
+               template_map.erase(name);
+               _E("Failed to get request: not supported");
+               return ERR_NOT_SUPPORTED;
+       }
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get request");
+
+       template_map[name] = tmpl;
+
+       return ERR_NONE;
+}
+
+void rule_validator::remove_template(std::string name)
+{
+       template_map.erase(name);
+}
+
+// called by context_trigger_rule_add_entry()
+bool rule_validator::check_option(CtxJson1& item)
+{
+       std::string name;
+       item.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       // No option needed
+       CtxJson1 opt_tmpl;
+       tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
+
+       std::list<std::string> opt_keys;
+       IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
+       if (opt_keys.size() <= 0) {
+               return true;
+       }
+
+       // Err: Check if mandatory option is missed
+       std::string val_str;
+       int val;
+       if (name == SUBJ_PLACE_GEOFENCE) {
+               if (!(item.get(OLD_TRIG_RULE_KEY_EVENT_OPTION, CONTEXT_TRIGGER_PLACE_ID, &val)))
+                       return false;
+       } else if (name == SUBJ_APP_FREQUENCY) {
+               if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_APP_ID, &val_str)))
+                       return false;
+       } else if (name == SUBJ_SOCIAL_FREQUENCY) {
+               if (!(item.get(OLD_TRIG_RULE_KEY_CONDITION_OPTION, CONTEXT_TRIGGER_ADDRESS, &val_str)))
+                       return false;
+       }
+
+       return true;
+}
+
+// called by context_trigger_rule_entry_add_option_int()
+bool rule_validator::check_option_int(std::string name, std::string key, int value)
+{
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       CtxJson1 opt_tmpl;
+       tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
+
+       // Err: Item with no option
+       std::list<std::string> opt_keys;
+       IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
+       IF_FAIL_RETURN(opt_keys.size() > 0, false);
+
+       // Err: Invalid option key or Invalid value type
+       std::string t_type = get_data_type(opt_tmpl, key);
+       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
+
+       // Err: Inappropriate value
+       //   a. normal case
+       bool ret = check_value_int(opt_tmpl, key, value);
+       IF_FAIL_RETURN(ret, false);
+
+       return true;
+}
+
+// called by context_trigger_rule_entry_add_option_string()
+bool rule_validator::check_option_string(std::string name, std::string key, std::string value)
+{
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       CtxJson1 opt_tmpl;
+       tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
+
+       // Err: ';' for SQL injection
+       IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
+
+       // Err: Item with no option
+       std::list<std::string> opt_keys;
+       IF_FAIL_RETURN(opt_tmpl.getKeys(&opt_keys), false);
+       IF_FAIL_RETURN(opt_keys.size() > 0, false);
+
+       // Err: Invalid option key or Invalid value type
+       std::string t_type = get_data_type(opt_tmpl, key);
+       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
+
+       // Err: Inappropriate value
+       //   a. spacial case
+       if (t_type == TRIG_TMPL_TYPE_STRING && (name == SUBJ_APP_FREQUENCY || name == SUBJ_SOCIAL_FREQUENCY
+                       || name == SUBJ_MUSIC_FREQUENCY || name == SUBJ_VIDEO_FREQUENCY)
+                       && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
+               std::size_t found = value.find("-");
+               if (found == std::string::npos) {
+                       return false;
+               }
+
+               int t1 = string_to_int(value.substr(0, found-1));
+               int t2 = string_to_int(value.substr(found+1, value.length()-1));
+
+               if (!(t1 >= 0 && t1 < 24) || !(t2 >= 0 && t2 < 24)) {
+                       return false;
+               }
+
+               if (t1 >= t2) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       //   b. normal case
+       bool ret = false;
+       if (t_type == TRIG_TMPL_TYPE_STRING) {
+               ret = check_value_string(opt_tmpl, key, value);
+       } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
+               ret = check_value_enum(opt_tmpl, key, value);
+       }
+
+       return ret;
+}
+
+// called by context_trigger_rule_entry_add_comparison_int()
+bool rule_validator::check_comparison_int(std::string name, std::string key, std::string op, int value)
+{
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       CtxJson1 attr_tmpl;
+       tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
+
+       // Err: Invalid attribute key or Invalid value type
+       std::string t_type = get_data_type(attr_tmpl, key);
+       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_INTEGER, false);
+
+       // Err: Invalid operator for the value
+       //    a. normal case
+       bool ret = is_valid_operator(TRIG_TMPL_TYPE_INTEGER, op);
+       IF_FAIL_RETURN(ret, false);
+       //    b. special case
+       if (name == SUBJ_STATE_ALARM && key == CONTEXT_TRIGGER_TIME_OF_DAY) {
+               IF_FAIL_RETURN(op == CONTEXT_TRIGGER_EQUAL_TO, false);
+       }
+
+       // Err: Inappropriate value
+       //    a. normal case
+       ret = check_value_int(attr_tmpl, key, value);
+       IF_FAIL_RETURN(ret, false);
+
+       return true;
+}
+
+// called by context_trigger_rule_entry_add_comparison_string()
+bool rule_validator::check_comparison_string(std::string name, std::string key, std::string op, std::string value)
+{
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != CtxJson1(EMPTY_JSON_OBJECT), false);
+
+       CtxJson1 attr_tmpl;
+       tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
+
+       // Err: ';' for SQL injection
+       IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
+
+       // Err: Invalid option key or Invalid value type
+       std::string t_type = get_data_type(attr_tmpl, key);
+       IF_FAIL_RETURN(t_type == TRIG_TMPL_TYPE_STRING || t_type == TRIG_TMPL_TYPE_ENUM, false);
+
+       // Err: Invalid operator for the value
+       bool ret = is_valid_operator(t_type, op);
+       IF_FAIL_RETURN(ret, false);
+
+       // Err: Inappropriate value
+       //    a. normal case
+       if (t_type == TRIG_TMPL_TYPE_STRING) {
+               ret = check_value_string(attr_tmpl, key, value);
+               IF_FAIL_RETURN(ret, false);
+       } else if (t_type == TRIG_TMPL_TYPE_ENUM) {
+               ret = check_value_enum(attr_tmpl, key, value);
+               IF_FAIL_RETURN(ret, false);
+       }
+
+       return true;
+}
+
+bool rule_validator::check_valid_key(std::string type, std::string name, std::string key)
+{
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       // Err: Invalid key
+       CtxJson1 tmp;
+       bool ret = tmpl.get(type.c_str(), key.c_str(), &tmp);
+       IF_FAIL_RETURN(ret, false);
+
+       return true;
+}
+
+bool check_value_int(CtxJson1& tmpl, std::string key, int value)
+{
+       int min, max;
+
+       if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MIN, &min)) {
+               IF_FAIL_RETURN(value >= min, false);
+       }
+
+       if (tmpl.get(key.c_str(), TRIG_TMPL_KEY_MAX, &max)) {
+               IF_FAIL_RETURN(value <= max, false);
+       }
+
+       return true;
+}
+
+bool check_value_string(CtxJson1& tmpl, std::string key, std::string value)
+{
+       return true;
+}
+
+bool check_value_enum(CtxJson1& tmpl, std::string key, std::string value)
+{
+       std::string t_val;
+       for (int i = 0; tmpl.getAt(key.c_str(), TRIG_TMPL_TYPE_ENUM, i, &t_val); i++) {
+               if (t_val == value)
+                       return true;
+       }
+
+       return false;
+}
+
+// called by context_trigger_rule_entry_add_comparison()
+// called by context_trigger_rule_entry_add_option()
+bool rule_validator::set_ref_info(std::string type, CtxJson1* jref, std::string name, std::string key, std::string ref_data)
+{
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       CtxJson1 detailed_tmpl;
+       tmpl.get(NULL, type.c_str(), &detailed_tmpl);
+
+       std::string dt = get_data_type(detailed_tmpl, key);
+       IF_FAIL_RETURN(dt == TRIG_TMPL_TYPE_INTEGER || dt == TRIG_TMPL_TYPE_STRING || dt == TRIG_TMPL_TYPE_ENUM, false);
+
+       CtxJson1 temp;
+       temp.set(NULL, RULE_VALIDATOR_COND_NAME, name);
+       temp.set(NULL, RULE_VALIDATOR_KEY, key);
+       temp.set(NULL, RULE_VALIDATOR_TYPE, dt);
+       temp.set(NULL, RULE_VALIDATOR_REF, ref_data);
+
+       if (type == TRIG_TMPL_KEY_OPTION) {
+               jref->append(NULL, TRIG_TMPL_KEY_OPTION, temp);
+       } else if (type == TRIG_TMPL_KEY_ATTRIBUTE) {
+               jref->append(NULL, TRIG_TMPL_KEY_ATTRIBUTE, temp);
+       } else {
+               return false;
+       }
+
+       return true;;
+}
+
+std::string get_data_type(CtxJson1& elem, std::string& key)
+{
+       std::string data_type;
+       bool ret = elem.get(key.c_str(), TRIG_TMPL_KEY_TYPE, &data_type);
+       if (!ret) {
+               int size = elem.getSize(key.c_str(), TRIG_TMPL_TYPE_ENUM);
+               IF_FAIL_RETURN(size > 0, "");
+               data_type = TRIG_TMPL_TYPE_ENUM;
+       }
+       IF_FAIL_RETURN(data_type == TRIG_TMPL_TYPE_INTEGER || data_type == TRIG_TMPL_TYPE_STRING || data_type == TRIG_TMPL_TYPE_ENUM, "");
+
+       return data_type;
+}
+
+// called by context_trigger_rule_entry_add_comparison()
+std::string rule_validator::get_data_type_from_template(std::string type, std::string name, std::string key)
+{
+       CtxJson1 tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, "");
+
+       CtxJson1 detailed_tmpl;
+       tmpl.get(NULL, type.c_str(), &detailed_tmpl);
+
+       return get_data_type(detailed_tmpl, key);
+}
+
+// called by context_trigger_rule_add_entry()
+bool rule_validator::check_referential_data(std::string name, CtxJson1& ref_info)
+{
+       std::map<std::string, std::string> type_map;
+
+       CtxJson1 ref_data;
+       for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_OPTION, i, &ref_data); i++) {
+               std::string ref_key;
+               ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
+               std::string cond_type;
+               ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
+
+               if (type_map.count(ref_key) == 0) {
+                       type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
+               }
+
+               // Err: Invalid key or Value type not matched
+               IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
+       }
+
+       for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_ATTRIBUTE, i, &ref_data); i++) {
+               std::string ref_key;
+               ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
+               std::string cond_type;
+               ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
+
+               if (type_map.count(ref_key) == 0) {
+                       type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
+               }
+
+               // Err: Invalid key or Value type not matched
+               IF_FAIL_RETURN(is_equal_type(cond_type, type_map[ref_key]), false);
+       }
+
+       return true;
+}
+
+bool is_equal_type(std::string& type1, std::string& type2)
+{
+       // This function regards TRIG_TMPL_TYPE_ENUM as TRIG_TMPL_TYPE_STRING for referential data
+       if (type1 == type2) {
+               return true;
+       }
+
+       if ((type1 == TRIG_TMPL_TYPE_STRING || type1 == TRIG_TMPL_TYPE_ENUM) && (type2 == TRIG_TMPL_TYPE_STRING || type2 == TRIG_TMPL_TYPE_ENUM)) {
+               return true;
+       }
+
+       return false;
+}
+
+bool rule_validator::is_valid_operator(std::string type, std::string op)
+{
+       if (op == CONTEXT_TRIGGER_EQUAL_TO || op == CONTEXT_TRIGGER_NOT_EQUAL_TO) {
+               return true;
+       }
+
+       if (type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_DOUBLE) {
+               if (op == CONTEXT_TRIGGER_GREATER_THAN || op == CONTEXT_TRIGGER_GREATER_THAN_OR_EQUAL_TO ||
+                       op == CONTEXT_TRIGGER_LESS_THAN || op == CONTEXT_TRIGGER_LESS_THAN_OR_EQUAL_TO) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+// For custom item template
+bool rule_validator::is_valid_template(CtxJson1& attr_template)
+{
+       IF_FAIL_RETURN_TAG(attr_template != EMPTY_JSON_OBJECT, false, _E, "Custom template: empty CtxJson1");
+
+       bool ret;
+       std::list<std::string> keys;
+       attr_template.getKeys(&keys);
+
+       for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); it++) {
+               std::string key = *it;
+
+               std::string type = get_data_type(attr_template, key);
+               IF_FAIL_RETURN_TAG(type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM,
+                       false, _E, "Custom template: invalid data type");
+
+               CtxJson1 elem;
+               attr_template.get(NULL, key.c_str(), &elem);
+               if (type == TRIG_TMPL_TYPE_INTEGER) {
+                       ret = check_template_int(elem);
+                       IF_FAIL_RETURN(ret, false);
+               } else if (type == TRIG_TMPL_TYPE_STRING) {
+                       ret = check_template_string(elem);
+                       IF_FAIL_RETURN(ret, false);
+               } else if (type == TRIG_TMPL_TYPE_ENUM) {
+                       ret = check_template_enum(elem);
+                       IF_FAIL_RETURN(ret, false);
+               }
+       }
+
+       return true;
+}
+
+bool check_template_int(CtxJson1& elem)
+{
+       std::list<std::string> elem_keys;
+       elem.getKeys(&elem_keys);
+
+       bool min = false;
+       bool max = false;
+       int min_val = 0;
+       int max_val = 0;
+
+       for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
+               std::string elem_key = *it2;
+               if (elem_key == TRIG_TMPL_KEY_MIN) {
+                       min = elem.get(NULL, elem_key.c_str(), &min_val);
+                       IF_FAIL_RETURN_TAG(min, false, _E, "Custom template: failed to get integer type value");
+               } else if (elem_key == TRIG_TMPL_KEY_MAX) {
+                       max = elem.get(NULL, elem_key.c_str(), &max_val);
+                       IF_FAIL_RETURN_TAG(max, false, _E, "Custom template: failed to get integer type value");
+               } else {
+                       IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
+               }
+       }
+
+       if (min && max) {
+               IF_FAIL_RETURN_TAG(min_val <= max_val, false, _E, "Custom template: invalid min, max value");
+       }
+
+       return true;
+}
+
+bool check_template_string(CtxJson1& elem)
+{
+       std::list<std::string> elem_keys;
+       elem.getKeys(&elem_keys);
+
+       for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
+               std::string elem_key = *it2;
+               IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
+       }
+
+       return true;
+}
+
+bool check_template_enum(CtxJson1& elem)
+{
+       std::list<std::string> elem_keys;
+       elem.getKeys(&elem_keys);
+
+       for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
+               std::string elem_key = *it2;
+
+               if (elem_key == TRIG_TMPL_TYPE_ENUM) {
+                       int size = elem.getSize(NULL, TRIG_TMPL_TYPE_ENUM);
+                       IF_FAIL_RETURN_TAG(size > 0, false, _E, "Custom template: invalid enum");
+
+                       std::string val_str;
+                       for (int i = 0; i < size; i++) {
+                               bool ret = elem.getAt(NULL, TRIG_TMPL_TYPE_ENUM, i, &val_str);
+                               IF_FAIL_RETURN_TAG(ret, false, _E, "Custom template: failed to get string type value");
+                       }
+               } else {
+                       IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
+               }
+       }
+
+       return true;
+}
diff --git a/src/trigger/rule_validator.h b/src/trigger/rule_validator.h
new file mode 100644 (file)
index 0000000..688a295
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_RULE_VALIDATOR_H__
+#define __CONTEXT_RULE_VALIDATOR_H__
+
+#include <CtxJson1.h>
+
+namespace ctx {
+       namespace rule_validator {
+
+               int request_template(std::string name, bool mandatory = false);
+               void remove_template(std::string name);
+               bool check_option(ctx::CtxJson1 &item);
+               bool check_option_int(std::string name, std::string key, int value);
+               bool check_option_string(std::string name, std::string key, std::string value);
+               bool check_option_reference(std::string event, ctx::CtxJson1 &item);
+               bool check_comparison_int(std::string name, std::string key, std::string op, int value);
+               bool check_comparison_string(std::string name, std::string key, std::string op, std::string value);
+               bool check_valid_key(std::string type, std::string name, std::string key);
+
+               bool set_ref_info(std::string type, ctx::CtxJson1 *jref, std::string name, std::string key, std::string ref_key);
+               std::string get_data_type_from_template(std::string type, std::string name, std::string key);
+               bool check_referential_data(std::string name, ctx::CtxJson1 &ref_info);
+               bool is_valid_operator(std::string type, std::string op);
+
+               bool is_valid_template(ctx::CtxJson1& attr_template);
+       }
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_RULE_VALIDATOR_H__ */