Cherry pick from devel/tizen (Version 1.0.5) 90/146890/2 accepted/tizen/unified/20170904.144524 submit/tizen/20170904.032954
authorSomin Kim <somin926.kim@samsung.com>
Thu, 31 Aug 2017 04:16:24 +0000 (13:16 +0900)
committerSomin Kim <somin926.kim@samsung.com>
Mon, 4 Sep 2017 03:17:40 +0000 (12:17 +0900)
Fix custom fact validation
Fix coding rule
[trigger] Added template verification
[Trigger] Set trigger rule(sched job) as persistent
trigger: set the lower/upper bound of int comparisons considering its logical type
trigger: Implement rule info validators on ContextItem
trigger: implement API functions using the internal job scheduler API
Add custom context name checker (regex)
trigger: define API handle structures and static util functions
trigger: add the skeleton of the class CustomTemplate, which is used to validate custom facts
trigger: add the skeleton of the class ContextItem, which is used to verify event and condition items
trigger: add PrivilegeChecker
trigger: remove the legacy trigger API implementation

Change-Id: Ic088b30db291e293f3ca088769499f40e73d1f38
Signed-off-by: Somin Kim <somin926.kim@samsung.com>
20 files changed:
CMakeLists.txt
include/context_trigger.h
packaging/capi-context.spec
src/trigger/ComparisonConverter.cpp [deleted file]
src/trigger/ComparisonConverter.h [deleted file]
src/trigger/ContextItem.cpp [new file with mode: 0644]
src/trigger/ContextItem.h [new file with mode: 0644]
src/trigger/CustomTemplate.cpp [new file with mode: 0644]
src/trigger/CustomTemplate.h [new file with mode: 0644]
src/trigger/IntComparisonConverter.cpp [deleted file]
src/trigger/IntComparisonConverter.h [deleted file]
src/trigger/PrivilegeChecker.cpp [new file with mode: 0644]
src/trigger/PrivilegeChecker.h [moved from src/trigger/rule_util.h with 53% similarity]
src/trigger/StringComparisonConverter.cpp [deleted file]
src/trigger/StringComparisonConverter.h [deleted file]
src/trigger/TriggerOldRuleTypes.h [deleted file]
src/trigger/context_trigger.cpp
src/trigger/rule_util.cpp [deleted file]
src/trigger/rule_validator.cpp [deleted file]
src/trigger/rule_validator.h [deleted file]

index 0a8d060..97e5d3f 100644 (file)
@@ -6,9 +6,9 @@ INCLUDE(GNUInstallDirs)
 SET(target ${PROJECT_NAME})
 
 # Dependencies
-SET(DEPS "gio-2.0 jsoncpp bundle pkgmgr-info capi-base-common capi-appfw-app-control")
+SET(DEPS "gio-2.0 jsoncpp bundle aul pkgmgr-info capi-base-common capi-appfw-app-control")
+SET(DEPS "${DEPS} cynara-creds-self cynara-session cynara-client")
 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)
index 173caca..b3780c1 100644 (file)
@@ -22,9 +22,8 @@
  * @{
  */
 
-#include <tizen_error.h>
+#include <tizen.h>
 #include <app_control.h>
-#include <stdbool.h>
 
 #ifdef __cplusplus
 extern "C" {
index b71ab52..e4dba6c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-context
 Summary:    Tizen Context Framework Native API
-Version:    1.0.4
+Version:    1.0.5
 Release:    1
 Group:      Service Framework/Context
 License:    Apache-2.0
@@ -9,18 +9,17 @@ Source0:    %{name}-%{version}.tar.gz
 BuildRequires: cmake
 BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(jsoncpp)
-#BuildRequires: pkgconfig(aul)
 BuildRequires: pkgconfig(bundle)
+BuildRequires: pkgconfig(aul)
 BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: pkgconfig(capi-base-common)
 BuildRequires: pkgconfig(capi-appfw-app-control)
+BuildRequires: pkgconfig(cynara-creds-self)
+BuildRequires: pkgconfig(cynara-session)
+BuildRequires: pkgconfig(cynara-client)
 BuildRequires: pkgconfig(context-app-history-client)
 BuildRequires: pkgconfig(context-job-scheduler-client)
 
-# Legacy support
-BuildRequires: pkgconfig(context-common-legacy)
-Requires: context-agent
-
 # Backward compatibility
 Provides: context
 
diff --git a/src/trigger/ComparisonConverter.cpp b/src/trigger/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/trigger/ComparisonConverter.h b/src/trigger/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/trigger/ContextItem.cpp b/src/trigger/ContextItem.cpp
new file mode 100644 (file)
index 0000000..7943d4a
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2017 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 <vector>
+#include <algorithm>
+#include <json/json.h>
+#include <SharedUtil.h>
+#include <job_scheduler_internal.h>
+#include <job_scheduler_types_internal.h>
+#include <context_trigger.h>
+#include "PrivilegeChecker.h"
+#include "ContextItem.h"
+
+#define CTX_SCHED_URI_ALARM                    CTX_SCHED_URI_PREFIX "event/time"
+#define CTX_SCHED_URI_CALL                     CTX_SCHED_URI_PREFIX "state/email"
+#define CTX_SCHED_URI_EMAIL                    CTX_SCHED_URI_PREFIX "event/email"
+#define CTX_SCHED_URI_MESSAGE          CTX_SCHED_URI_PREFIX "event/message"
+#define CTX_SCHED_URI_APP_FREQ         CTX_SCHED_URI_PREFIX "stats/app"
+#define CTX_SCHED_URI_COMM_FREQ                CTX_SCHED_URI_PREFIX "stats/comm"
+#define CTX_SCHED_URI_MUSIC_FREQ       CTX_SCHED_URI_PREFIX "stats/music"
+#define CTX_SCHED_URI_VIDEO_FREQ       CTX_SCHED_URI_PREFIX "stats/video"
+
+#define URI(x)      CTX_SCHED_URI_##x
+#define NAME(x)     CTX_SCHED_ATTR_NAME_##x
+
+ContextItem::ContextItem(int cx) :
+       __context(cx),
+       __uri(NULL)
+{
+}
+
+bool ContextItem::allowed()
+{
+       return PrivilegeChecker::hasPrivilege(__getPrivilege());
+}
+
+bool ContextItem::isValid(ctx_sched_job_context_h jobContext)
+{
+       IF_FAIL_RETURN(jobContext, false);
+
+       struct MandatoryEntry {
+               const char* uri;
+               std::vector<const char*> attributes;
+       };
+
+       static std::vector<MandatoryEntry> mandatories = {
+               { URI(ALARM),           {NAME(TIME_OF_DAY)} },
+               { URI(GEOFENCE),        {NAME(PLACE_ID)} },
+               { URI(APP_FREQ),        {CONTEXT_TRIGGER_APP_ID} }
+               //TODO
+       };
+
+       const char* serialized = ctx_sched_job_context_serialize(jobContext);
+       IF_FAIL_RETURN(serialized, false);
+
+       Json::Value jCtx;
+
+       try {
+               Json::Reader reader;
+               if (!reader.parse(serialized, jCtx)) {
+                       _E("Parsing failed");
+                       return false;
+               }
+       } catch (const Json::Exception& e) {
+               _E("Exception: %s", e.what());
+               return false;
+       }
+
+       IF_FAIL_RETURN(jCtx.isMember("Attribute"), false);
+
+       Json::Value& attributes = jCtx["Attribute"];
+
+       for (auto& entry : mandatories) {
+               if (!STR_EQ(entry.uri, getUri()))
+                       continue;
+
+               for (auto& mandatoryAttr : entry.attributes) {
+                       // The mandatory attribute should be exist
+                       if (!attributes.isMember(mandatoryAttr))
+                               return false;
+
+                       // If exist, at least one target value needs to be designated
+                       if (attributes[mandatoryAttr]["Target"].size() == 0)
+                               return false;
+               }
+
+               return true;
+       }
+
+       return true;
+}
+
+bool ContextItem::isValidData(const char* attribute)
+{
+       return (isValidData(attribute, 1) || isValidData(attribute, static_cast<const char*>(NULL)));
+}
+
+bool ContextItem::isValidData(const char* attribute, int value)
+{
+       static std::vector<IntAttributeRange> attributeRanges = {
+               { URI(ALARM),           NAME(TIME_OF_DAY),      0,      1439 },
+               { URI(TIME),            NAME(TIME_OF_DAY),      0,      1439 },
+               { URI(TIME),            NAME(DAY_OF_MONTH),     1,      31 },
+               { URI(BATTERY),         NAME(IS_CHARGING),      0,      1 },
+               { URI(CHARGER),         NAME(IS_CONNECTED),     0,      1 },
+               { URI(EARJACK),         NAME(IS_CONNECTED),     0,      1 },
+               { URI(USB),                     NAME(IS_CONNECTED),     0,      1 },
+               { URI(POWERSAVE),       NAME(IS_ENABLED),       0,      1 }
+               //TODO: unsupported items
+       };
+
+       _D("Verify %s, %d", attribute, value);
+
+       return __isValid(attributeRanges, attribute, value);
+}
+
+bool ContextItem::isValidData(const char* attribute, const char* value)
+{
+       static std::vector<StrAttributeValues> attributeValues = {
+               { URI(ALARM),           NAME(DAY_OF_WEEK),      {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Weekday", "Weekend"} },
+               { URI(TIME),            NAME(DAY_OF_WEEK),      {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Weekday", "Weekend"} },
+               { URI(BATTERY),         NAME(LEVEL),    {"Empty", "Critical", "Low", "Normal", "High", "Full"} },
+               { URI(GEOFENCE),        NAME(EVENT),    {"In", "Out"} },
+               { URI(GPS),                     NAME(STATE),    {"Disabled", "Searching", "Connected"} },
+               { URI(EARJACK),         NAME(TYPE),             {"Normal", "Headset", "Bluetooth"} },
+               { URI(WIFI),            NAME(STATE),    {"Disabled", "Unconnected", "Connected"} },
+               { URI(WIFI),            NAME(BSSID),    {} },
+               { URI(STATIONARY),      NAME(EVENT),    {"Detected"} },
+               { URI(WALKING),         NAME(EVENT),    {"Detected"} },
+               { URI(RUNNING),         NAME(EVENT),    {"Detected"} },
+               { URI(IN_VEHICLE),      NAME(EVENT),    {"Detected"} },
+               { URI(CONTACTS_DB),     NAME(EVENT),    {"Changed"} },
+               { URI(CONTACTS_DB),     NAME(TYPE),             {"MyProfile", "Person"} }
+               //TODO: unsupported items
+       };
+
+       _D("Verify %s, %s", attribute, value);
+
+       return __isValid(attributeValues, attribute, value);
+}
+
+bool ContextItem::isValidOption(const char* attribute)
+{
+       return (isValidOption(attribute, 1) || isValidOption(attribute, static_cast<const char*>(NULL)));
+}
+
+bool ContextItem::isValidOption(const char* attribute, int value)
+{
+       static std::vector<IntAttributeRange> attributeRanges = {
+               { URI(GEOFENCE),        NAME(PLACE_ID), 1,      INT_MAX }
+               //TODO: unsupported items
+       };
+
+       _D("Verify %s, %d", attribute, value);
+
+       return __isValid(attributeRanges, attribute, value);
+}
+
+bool ContextItem::isValidOption(const char* attribute, const char* value)
+{
+       static std::vector<StrAttributeValues> attributeValues = {
+               { URI(STATIONARY),      NAME(ACCURACY), {"Low", "Normal", "High"} },
+               { URI(WALKING),         NAME(ACCURACY), {"Low", "Normal", "High"} },
+               { URI(RUNNING),         NAME(ACCURACY), {"Low", "Normal", "High"} },
+               { URI(IN_VEHICLE),      NAME(ACCURACY), {"Low", "Normal", "High"} }
+               //TODO: unsupported items
+       };
+
+       _D("Verify %s, %s", attribute, value);
+
+       return __isValid(attributeValues, attribute, value);
+}
+
+bool ContextItem::__isValid(const std::vector<IntAttributeRange>& attributeRanges, const char* attribute, int value)
+{
+       for (auto& range : attributeRanges) {
+               if (!STR_EQ(range.uri, getUri()))
+                       continue;
+
+               if (!STR_EQ(range.attribute, attribute))
+                       continue;
+
+               if (value < range.min || value > range.max)
+                       return false;
+
+               return true;
+       }
+
+       return false;
+}
+
+bool ContextItem::__isValid(const std::vector<StrAttributeValues>& attributeValues, const char* attribute, const char* value)
+{
+       for (auto& values : attributeValues) {
+               if (!STR_EQ(values.uri, getUri()))
+                       continue;
+
+               if (!STR_EQ(values.attribute, attribute))
+                       continue;
+
+               // NULL value is a wildcard
+               if (!value)
+                       return true;
+
+               // Accept any strings
+               if (values.values.empty())
+                       return true;
+
+               auto it = std::find_if(values.values.begin(), values.values.end(),
+                               [&value](const char* validValue)->bool {
+                                       return STR_EQ(value, validValue);
+                               });
+
+               if (it == values.values.end())
+                       return false;
+
+               return true;
+       }
+
+       return false;
+}
+
+EventItem::EventItem(int event) :
+       ContextItem(event)
+{
+}
+
+bool EventItem::deprecated()
+{
+       switch (__context) {
+       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:
+               return true;
+       default:
+               return false;
+       }
+}
+
+const char* EventItem::getUri()
+{
+       static const std::map<int, const char*> uriMap = {
+               {CONTEXT_TRIGGER_EVENT_TIME,                            URI(ALARM)},
+               {CONTEXT_TRIGGER_EVENT_BATTERY,             URI(BATTERY)},
+               {CONTEXT_TRIGGER_EVENT_CHARGER,             URI(CHARGER)},
+               {CONTEXT_TRIGGER_EVENT_GPS,                 URI(GPS)},
+               {CONTEXT_TRIGGER_EVENT_HEADPHONE,           URI(EARJACK)},
+               {CONTEXT_TRIGGER_EVENT_POWER_SAVING_MODE,   URI(POWERSAVE)},
+               {CONTEXT_TRIGGER_EVENT_USB,                 URI(USB)},
+               {CONTEXT_TRIGGER_EVENT_WIFI,                URI(WIFI)},
+               {CONTEXT_TRIGGER_EVENT_CALL,                            URI(CALL)},
+               {CONTEXT_TRIGGER_EVENT_EMAIL,                           URI(EMAIL)},
+               {CONTEXT_TRIGGER_EVENT_MESSAGE,                         URI(MESSAGE)},
+               {CONTEXT_TRIGGER_EVENT_CONTACTS,            URI(CONTACTS_DB)},
+               {CONTEXT_TRIGGER_EVENT_ACTIVITY_STATIONARY, URI(STATIONARY)},
+               {CONTEXT_TRIGGER_EVENT_ACTIVITY_WALKING,    URI(WALKING)},
+               {CONTEXT_TRIGGER_EVENT_ACTIVITY_RUNNING,    URI(RUNNING)},
+               {CONTEXT_TRIGGER_EVENT_ACTIVITY_IN_VEHICLE, URI(IN_VEHICLE)},
+               {CONTEXT_TRIGGER_EVENT_PLACE,               URI(GEOFENCE)}
+       };
+
+       if (__uri) return __uri;
+
+       auto it = uriMap.find(__context);
+
+       if (it == uriMap.end())
+               return NULL;
+
+       return (__uri = it->second);
+}
+
+const char* EventItem::__getPrivilege()
+{
+       if (CONTEXT_TRIGGER_EVENT_TIME == __context)
+               return "http://tizen.org/privilege/alarm.set";
+
+       if (CONTEXT_TRIGGER_EVENT_WIFI == __context)
+               return "http://tizen.org/privilege/network.get";
+
+       if (CONTEXT_TRIGGER_EVENT_CALL == __context)
+               return "http://tizen.org/privilege/telephony";
+
+       if (CONTEXT_TRIGGER_EVENT_MESSAGE == __context)
+               return "http://tizen.org/privilege/message.read";
+
+       if (CONTEXT_TRIGGER_EVENT_CONTACTS == __context)
+               return "http://tizen.org/privilege/contact.read";
+
+       if (CONTEXT_TRIGGER_EVENT_PLACE == __context)
+               return "http://tizen.org/privilege/location";
+
+       return NULL;
+}
+
+ConditionItem::ConditionItem(int cond) :
+       ContextItem(cond)
+{
+}
+
+bool ConditionItem::deprecated()
+{
+       switch (__context) {
+       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:
+               return true;
+       default:
+               return false;
+       }
+}
+
+const char* ConditionItem::getUri()
+{
+       static const std::map<int, const char*> uriMap = {
+               {CONTEXT_TRIGGER_CONDITION_TIME,              URI(TIME)},
+               {CONTEXT_TRIGGER_CONDITION_BATTERY,           URI(BATTERY)},
+               {CONTEXT_TRIGGER_CONDITION_CHARGER,           URI(CHARGER)},
+               {CONTEXT_TRIGGER_CONDITION_GPS,               URI(GPS)},
+               {CONTEXT_TRIGGER_CONDITION_HEADPHONE,         URI(EARJACK)},
+               {CONTEXT_TRIGGER_CONDITION_POWER_SAVING_MODE, URI(POWERSAVE)},
+               {CONTEXT_TRIGGER_CONDITION_USB,               URI(USB)},
+               {CONTEXT_TRIGGER_CONDITION_WIFI,              URI(WIFI)},
+               {CONTEXT_TRIGGER_CONDITION_CALL,                     URI(CALL)},
+               {CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY,        URI(APP_FREQ)},
+               {CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY,  URI(COMM_FREQ)},
+               {CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY, URI(MUSIC_FREQ)},
+               {CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY, URI(VIDEO_FREQ)}
+       };
+
+       if (__uri) return __uri;
+
+       auto it = uriMap.find(__context);
+
+       if (it == uriMap.end())
+               return NULL;
+
+       return (__uri = it->second);
+}
+
+const char* ConditionItem::__getPrivilege()
+{
+       if (CONTEXT_TRIGGER_CONDITION_WIFI == __context)
+               return "http://tizen.org/privilege/network.get";
+
+       if (CONTEXT_TRIGGER_CONDITION_CALL == __context)
+               return "http://tizen.org/privilege/telephony";
+
+       if (CONTEXT_TRIGGER_CONDITION_APP_USE_FREQUENCY == __context)
+               return "http://tizen.org/privilege/apphistory.read";
+
+       if (CONTEXT_TRIGGER_CONDITION_COMMUNICATION_FREQUENCY == __context)
+               return "http://tizen.org/privilege/callhistory.read";
+
+       if (CONTEXT_TRIGGER_CONDITION_MUSIC_PLAYBACK_FREQUENCY == __context)
+               return "http://tizen.org/privilege/mediahistory.read";
+
+       if (CONTEXT_TRIGGER_CONDITION_VIDEO_PLAYBACK_FREQUENCY == __context)
+               return "http://tizen.org/privilege/mediahistory.read";
+
+       return NULL;
+}
diff --git a/src/trigger/ContextItem.h b/src/trigger/ContextItem.h
new file mode 100644 (file)
index 0000000..dd555b9
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 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_CONTEXT_ITEM_H__
+#define __CONTEXT_TRIGGER_CONTEXT_ITEM_H__
+
+#include <ContextTypes.h>
+#include <job_scheduler_internal.h>
+
+
+class ContextItem {
+public:
+       virtual ~ContextItem() {}
+
+       virtual bool deprecated() = 0;
+       virtual const char* getUri() = 0;
+
+       bool allowed();
+
+       bool isValid(ctx_sched_job_context_h jobContext);
+
+       bool isValidData(const char* attribute);
+       bool isValidData(const char* attribute, int value);
+       bool isValidData(const char* attribute, const char* value);
+
+       bool isValidOption(const char* attribute);
+       bool isValidOption(const char* attribute, int value);
+       bool isValidOption(const char*, const char* value);
+
+protected:
+       ContextItem(int cx);
+
+       int __context;
+       const char* __uri;
+
+private:
+       virtual const char* __getPrivilege() = 0;
+
+       struct IntAttributeRange {
+               const char* uri;
+               const char* attribute;
+               int min;
+               int max;
+       };
+
+       struct StrAttributeValues {
+               const char* uri;
+               const char* attribute;
+               std::vector<const char*> values;
+       };
+
+       bool __isValid(const std::vector<IntAttributeRange>& attributeRanges, const char* attribute, int value);
+       bool __isValid(const std::vector<StrAttributeValues>& attributeValues, const char* attribute, const char* value);
+};
+
+
+class EventItem : public ContextItem {
+public:
+       EventItem(int event);
+
+       bool deprecated();
+       const char* getUri();
+
+private:
+       const char* __getPrivilege();
+};
+
+
+class ConditionItem : public ContextItem {
+public:
+       ConditionItem(int cond);
+
+       bool deprecated();
+       const char* getUri();
+
+private:
+       const char* __getPrivilege();
+};
+
+
+#endif /* __CONTEXT_TRIGGER_CONTEXT_ITEM_H__ */
diff --git a/src/trigger/CustomTemplate.cpp b/src/trigger/CustomTemplate.cpp
new file mode 100644 (file)
index 0000000..93031eb
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2017 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 <regex>
+#include <context_trigger.h>
+#include "CustomTemplate.h"
+
+#define CT_KEY_MIN "minimum"
+#define CT_KEY_MAX "maximum"
+#define CT_KEY_TYPE "type"
+#define CT_TYPE_INTEGER "integer"
+#define CT_TYPE_STRING "string"
+#define CT_TYPE_ENUM "enum"
+#define CT_TYPE_DOUBLE "double"
+
+static std::list<CustomTemplate> __instances;
+
+CustomTemplate::CustomTemplate(const std::string& name, const Json::Value& templateJson) :
+       __name(name),
+       __templateJson(templateJson)
+{
+}
+
+const std::string& CustomTemplate::getName() const
+{
+       return __name;
+}
+
+int CustomTemplate::match(const std::string& fact)
+{
+       // true if the given fact is valid w.r.t. the template
+       Json::Reader reader;
+       Json::Value factJson;
+
+       // Error: Invalid Json
+       if (!reader.parse(fact, factJson)) {
+               _E("Fact: invalid json");
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       // Error: Invalid fact
+       IF_FAIL_RETURN_TAG(isValidFact(__templateJson, factJson), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid fact");
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+bool CustomTemplate::isValidFact(const Json::Value& tmplJson, const Json::Value& factJson)
+{
+       Json::Value::Members keys = factJson.getMemberNames();
+
+       std::string dataType;
+       for (auto& key : keys) {
+               // Get type
+               if (tmplJson[key].isMember(CT_TYPE_ENUM)) {
+                       dataType = CT_TYPE_ENUM;
+               } else if (tmplJson[key].isMember(CT_KEY_TYPE)) {
+                       dataType = tmplJson[key][CT_KEY_TYPE].asString();
+               }
+
+               if (dataType == CT_TYPE_INTEGER) {
+                       IF_FAIL_RETURN_TAG(factJson[key].isInt(), false, _E, "Custom fact: Invalid data type");
+
+                       int val = factJson[key].asInt();
+                       if (tmplJson[key].isMember(CT_KEY_MIN)) {
+                               IF_FAIL_RETURN_TAG(val >= tmplJson[key][CT_KEY_MIN].asInt(), false, _E, "Custom fact: Invalid value");
+                       }
+                       if (tmplJson[key].isMember(CT_KEY_MAX)) {
+                               IF_FAIL_RETURN_TAG(val <= tmplJson[key][CT_KEY_MAX].asInt(), false, _E, "Custom fact: Invalid value");
+                       }
+               } else if (dataType == CT_TYPE_STRING) {
+                       IF_FAIL_RETURN_TAG(factJson[key].isString(), false, _E, "Custom fact: Invalid data type");
+               } else if (dataType == CT_TYPE_ENUM) {
+                       IF_FAIL_RETURN_TAG(factJson[key].isString(), false, _E, "Custom fact: Invalid data type");
+
+                       std::string val = factJson[key].asString();
+
+                       bool found = false;
+                       for (unsigned int i = 0; i < tmplJson[key][CT_TYPE_ENUM].size(); i++) {
+                               std::string tmplValue = tmplJson[key][CT_TYPE_ENUM][i].asString();
+                               if (tmplValue == val)
+                                       found = true;
+                       }
+                       IF_FAIL_RETURN_TAG(found, false, _E, "Custom fact: Invalid value");
+               } else {
+                       _E("Custom fact: Invalid data type");
+                       return false;
+               }
+       }
+       return true;
+}
+
+bool CustomTemplate::isValidTemplate(const Json::Value& tmplJson)
+{
+       bool success = false;
+       Json::Value::Members keys = tmplJson.getMemberNames();
+
+       std::string dataType;
+       for (auto& key : keys) {
+               // Get type
+               if (tmplJson[key].isMember(CT_TYPE_ENUM)) {
+                       success = tmplJson[key][CT_TYPE_ENUM].isArray();
+                       IF_FAIL_RETURN_TAG(success, false, _E, "Invalid template");
+                       dataType = CT_TYPE_ENUM;
+               } else if (tmplJson[key].isMember(CT_KEY_TYPE)) {
+                       dataType = tmplJson[key][CT_KEY_TYPE].asString();
+                       IF_FAIL_RETURN_TAG(dataType == CT_TYPE_INTEGER || dataType == CT_TYPE_STRING,
+                               false, _E, "Invalid template");
+               }
+
+               if (dataType == CT_TYPE_INTEGER) {
+                       success = checkTemplateInt(tmplJson[key]);
+                       IF_FAIL_RETURN(success, false);
+               } else if (dataType == CT_TYPE_STRING) {
+                       success = checkTemplateString(tmplJson[key]);
+                       IF_FAIL_RETURN(success, false);
+               } else if (dataType == CT_TYPE_ENUM) {
+                       success = checkTemplateEnum(tmplJson[key]);
+                       IF_FAIL_RETURN(success, false);
+               }
+       }
+
+       return true;
+}
+
+bool CustomTemplate::checkTemplateInt(const Json::Value& elem)
+{
+       bool min = false;
+       bool max = false;
+       int minVal = 0;
+       int maxVal = 0;
+
+       Json::Value::Members elemKeys = elem.getMemberNames();
+
+       for (auto& elemKey : elemKeys) {
+               if (elemKey == CT_KEY_MIN) {
+                       min = true;
+                       minVal = elem[elemKey].asInt();
+               } else if (elemKey == CT_KEY_MAX) {
+                       max = true;
+                       maxVal = elem[elemKey].asInt();
+               } else {
+                       IF_FAIL_RETURN_TAG(elemKey == CT_KEY_TYPE, false, _E, "invalid key");
+               }
+       }
+
+       if (min && max) {
+               IF_FAIL_RETURN_TAG(minVal <= maxVal, false, _E, "Invalid min, max value");
+       }
+
+       return true;
+}
+
+bool CustomTemplate::checkTemplateString(const Json::Value& elem)
+{
+       Json::Value::Members elemKeys = elem.getMemberNames();
+
+       for (auto& elemKey : elemKeys) {
+               IF_FAIL_RETURN_TAG(elemKey == CT_KEY_TYPE, false, _E, "invalid key");
+       }
+
+       return true;
+}
+
+bool CustomTemplate::checkTemplateEnum(const Json::Value& elem)
+{
+       Json::Value::Members elemKeys = elem.getMemberNames();
+
+       for (auto& elemKey : elemKeys) {
+               if (elemKey == CT_TYPE_ENUM) {
+                       IF_FAIL_RETURN_TAG(!elem[CT_TYPE_ENUM].empty(), false, _E, "Invalid enum");
+
+                       for (unsigned int i = 0; i < elem[CT_TYPE_ENUM].size(); i++) {
+                               IF_FAIL_RETURN_TAG(elem[CT_TYPE_ENUM][i].isString(), false, _E, "Enum value sholud be string");
+                       }
+               } else {
+                       IF_FAIL_RETURN_TAG(elemKey == CT_KEY_TYPE, false, _E, "invalid key");
+               }
+       }
+
+       return true;
+}
+
+int CustomTemplate::add(const std::string& name, const std::string& attrTmpl)
+{
+       static std::regex nameRegex(R"~(^[\w-\._\/]+$)~", std::regex::optimize);
+       IF_FAIL_RETURN_TAG(std::regex_match(name, nameRegex), CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Invalid name");
+
+       Json::Reader reader;
+       Json::Value tmplJson;
+
+       // Error: Invalid Json
+       if (!reader.parse(attrTmpl, tmplJson)) {
+               _E("Template: invalid json");
+               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       }
+
+       // Error: already exist
+       CustomTemplate* tmpl = get(name);
+       if (tmpl) {
+               if (tmplJson == tmpl->__templateJson) {
+                       return CONTEXT_TRIGGER_ERROR_NONE;
+               } else {
+                       _E("Template already exists");
+                       return CONTEXT_TRIGGER_ERROR_DATA_EXIST;
+               }
+       }
+
+       // Error: Invalid template
+       IF_FAIL_RETURN_TAG(isValidTemplate(tmplJson), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "Invalid template");
+
+       __instances.emplace_back(name, tmplJson);
+
+       return CONTEXT_TRIGGER_ERROR_NONE;
+}
+
+void CustomTemplate::remove(const std::string& name)
+{
+       __instances.remove_if(
+                       [&name](const CustomTemplate& tmpl)->bool {
+                               return tmpl.getName() == name;
+                       });
+}
+
+CustomTemplate* CustomTemplate::get(const std::string& name)
+{
+       for (auto& tmpl : __instances) {
+               if (tmpl.getName() == name)
+                       return &tmpl;
+       }
+
+       return NULL;
+}
diff --git a/src/trigger/CustomTemplate.h b/src/trigger/CustomTemplate.h
new file mode 100644 (file)
index 0000000..2bbf579
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 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_CUSTOM_TEMPLATE_H__
+#define __CONTEXT_TRIGGER_CUSTOM_TEMPLATE_H__
+
+#include <string>
+#include <list>
+#include <json/json.h>
+#include <ContextTypes.h>
+
+class CustomTemplate {
+public:
+       CustomTemplate(const std::string& name, const Json::Value& templateJson);
+
+       const std::string& getName() const;
+       int match(const std::string& fact);
+
+       static int add(const std::string& name, const std::string& attrTmpl);
+       static void remove(const std::string& name);
+       static CustomTemplate* get(const std::string& name);
+
+       static bool isValidTemplate(const Json::Value& tmplJson);
+       static bool checkTemplateInt(const Json::Value& elem);
+       static bool checkTemplateString(const Json::Value& elem);
+       static bool checkTemplateEnum(const Json::Value& elem);
+       static bool isValidFact(const Json::Value& tmplJson, const Json::Value& factJson);
+
+
+private:
+       std::string __name;
+       Json::Value __templateJson;
+};
+
+#endif
diff --git a/src/trigger/IntComparisonConverter.cpp b/src/trigger/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/trigger/IntComparisonConverter.h b/src/trigger/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/trigger/PrivilegeChecker.cpp b/src/trigger/PrivilegeChecker.cpp
new file mode 100644 (file)
index 0000000..fe39067
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017 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 <cynara-creds-self.h>
+#include <cynara-session.h>
+#include <ScopeMutex.h>
+#include "PrivilegeChecker.h"
+
+#define CACHE_SIZE     10
+
+static GMutex __cynaraMutex;
+
+PrivilegeChecker::PrivilegeChecker() :
+       __client(NULL),
+       __session(NULL),
+       __user(NULL),
+       __cynara(NULL)
+{
+       cynara_creds_self_get_client(CLIENT_METHOD_DEFAULT, &__client);
+       cynara_creds_self_get_user(USER_METHOD_DEFAULT, &__user);
+
+       __session = cynara_session_from_pid(getpid());
+
+       if (!__client || !__user || !__session) {
+               _E("Self credentialing failed");
+               return;
+       }
+
+       cynara_configuration* conf = NULL;
+       int err = cynara_configuration_create(&conf);
+       IF_FAIL_VOID_TAG(err == CYNARA_API_SUCCESS, _E, "Cynara configuration creation failed");
+
+       err = cynara_configuration_set_cache_size(conf, CACHE_SIZE);
+       if (err != CYNARA_API_SUCCESS) {
+               _E("Cynara cache size set failed");
+               cynara_configuration_destroy(conf);
+               return;
+       }
+
+       err = cynara_initialize(&__cynara, conf);
+       cynara_configuration_destroy(conf);
+       if (err != CYNARA_API_SUCCESS) {
+               _E("Cynara initialization failed");
+               __cynara = NULL;
+               return;
+       }
+
+       _I("Cynara initialized");
+}
+
+PrivilegeChecker::~PrivilegeChecker()
+{
+       g_free(__client);
+       g_free(__session);
+       g_free(__user);
+
+       if (__cynara)
+               cynara_finish(__cynara);
+}
+
+bool PrivilegeChecker::hasPrivilege(const char* privil)
+{
+       if (!privil)
+               return true;
+
+       ctx::ScopeMutex sm(&__cynaraMutex);
+
+       static PrivilegeChecker checker;
+
+       return checker.__hasPrivilege(privil);
+}
+
+bool PrivilegeChecker::__hasPrivilege(const char* privil)
+{
+       IF_FAIL_RETURN_TAG(__cynara, false, _E, "Cynara not initialized");
+       int ret = cynara_check(__cynara, __client, __session, __user, privil);
+       _D("Check %s -> %d", privil, ret);
+       return (ret == CYNARA_API_ACCESS_ALLOWED);
+}
similarity index 53%
rename from src/trigger/rule_util.h
rename to src/trigger/PrivilegeChecker.h
index d4443bb..3e272da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
  * limitations under the License.
  */
 
-#ifndef __CONTEXT_RULE_UTIL_H__
-#define __CONTEXT_RULE_UTIL_H__
+#ifndef __CONTEXT_TRIGGER_PRIVILEGE_CHECKER_H__
+#define __CONTEXT_TRIGGER_PRIVILEGE_CHECKER_H__
 
-#include <CtxJson1.h>
+#include <cynara-client.h>
+#include <ContextTypes.h>
 
-namespace ctx {
+class PrivilegeChecker {
+public:
+       static bool hasPrivilege(const char* privil);
 
-       namespace rule_util {
+private:
+       PrivilegeChecker();
+       ~PrivilegeChecker();
 
-               int setEvent(CtxJson1& entry, CtxJson1* rule);
-               int addCondition(CtxJson1& entry, CtxJson1* rule);
-               bool isEventSet(CtxJson1& rule);
-               bool isActionSet(CtxJson1& rule);
+       bool __hasPrivilege(const char* privil);
 
-       }
-}      /* namespace ctx */
+       char* __client;
+       char* __session;
+       char* __user;
+       cynara* __cynara;
+};
 
-#endif /* __CONTEXT_RULE_UTIL_H__ */
+#endif /* __CONTEXT_TRIGGER_PRIVILEGE_CHECKER_H__ */
diff --git a/src/trigger/StringComparisonConverter.cpp b/src/trigger/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/trigger/StringComparisonConverter.h b/src/trigger/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/trigger/TriggerOldRuleTypes.h b/src/trigger/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_ */
index de50622..730bbac 100644 (file)
  * limitations under the License.
  */
 
-//#include <sstream>
-//#include <iomanip>
+#include <string>
+#include <vector>
+#include <set>
+#include <map>
+#include <algorithm>
+
 #include <app_control_internal.h>
-#include <bundle.h>
-#include <bundle_internal.h>
+#include <aul.h>
 #include <pkgmgr-info.h>
+
+#include <ContextTypes.h>
+#include <SharedUtil.h>
+#include <ScopeMutex.h>
+#include <job_scheduler_internal.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);
+
+#include "PrivilegeChecker.h"
+#include "ContextItem.h"
+#include "CustomTemplate.h"
+
+#define _DEPRECATED_FUNC               _W("DEPRECATION WARNING: %s is deprecated and will be removed from next release.", __FUNCTION__)
+#define _DEPRECATED_EVENT(id)  _W("DEPRECATION WARNING: This event (%d) is deprecated and will be removed from next release.", (id))
+#define _DEPRECATED_COND(id)   _W("DEPRECATION WARNING: This condition (%d) is deprecated and will be removed from next release.", (id))
+
+#define ASSERT_ALLOC(X)                IF_FAIL_RETURN_TAG(X, E_NO_MEM, _E, E_STR_ALLOC)
+#define ASSERT_NOT_NULL(X)     IF_FAIL_RETURN_TAG(X, E_PARAM, _E, "Parameter null")
+#define INIT_SCHED                     IF_FAIL_RETURN_TAG(__scheduler.get(), E_SUPPORT, _E, "Job scheduler is not supported")
+#define SCHED                          __scheduler.get()
+
+#define PKG_ID_LENGTH 128
+
+enum EntryCategory {
+       CATEGORY_EVENT          = 1,
+       CATEGORY_CONDITION      = 2
+};
+
+enum class OpType {
+       UNDEFINED = 0,
+       EQ,     // equals to
+       NE,     // not equals to
+       GT,     // greater than
+       GE,     // greater than or equals to
+       LT,     // less than
+       LE      // less than or equals to
+};
 
 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;
+       ctx_sched_job_h job;
+       bool readOnly;
+       bool hasEvent;
+       bool hasAction;
+       std::set<std::string> conditions;
+
+       _context_trigger_rule_s() :
+               job(NULL), readOnly(false), hasEvent(false), hasAction(false)
+       {
+               ctx_sched_job_create_on_demand(&job);
+       }
+
+       _context_trigger_rule_s(ctx_sched_job_h j) :
+               job(j), readOnly(true), hasEvent(true), hasAction(true)
+       {
+       }
+
+       ~_context_trigger_rule_s()
+       {
+               ctx_sched_job_destroy(job);
        }
 } _context_trigger_rule_h;
 
+
 typedef struct _context_trigger_rule_entry_s {
+       int category;
        int type;
-       ctx::CtxJson1 jentry;
-       ctx::CtxJson1 jref;
+       std::string uri;
+       ctx_sched_job_context_h jobContext;
+
+       struct Bound {
+               bool conjunction;
+               int gt;
+               int ge;
+               int lt;
+               int le;
+
+               Bound(bool conj) :
+                       conjunction(conj)
+               {
+                       if (conj) {
+                               gt = INT_MIN;
+                               ge = INT_MIN;
+                               lt = INT_MAX;
+                               le = INT_MAX;
+                       } else {
+                               gt = INT_MAX;
+                               ge = INT_MAX;
+                               lt = INT_MIN;
+                               le = INT_MIN;
+                       }
+               }
+       };
 
-       _context_trigger_rule_entry_s(int t): type(t) {
-               jentry = OLD_INITIAL_ENTRY;
+       std::map<std::string, Bound> attributes;
 
-               if (t == TYPE_CONDITION) {
-                       jref = INITIAL_REF;
-               }
+       _context_trigger_rule_entry_s(int c, int t, const char* u) :
+               category(c), type(t), uri(u), jobContext(NULL)
+       {
+               if (category == CATEGORY_EVENT)
+                       ctx_sched_job_trigger_create(uri.c_str(), &jobContext);
+               else
+                       ctx_sched_job_requirement_create(uri.c_str(), false, &jobContext);
+       }
+
+       ~_context_trigger_rule_entry_s()
+       {
+               ctx_sched_job_context_destroy(jobContext);
        }
 } _context_trigger_rule_entry_h;
 
-// Add a rule
-SO_EXPORT int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
+
+namespace {
+       class Scheduler {
+       private:
+               ctx_sched_h __scheduler;
+
+       public:
+               Scheduler() : __scheduler(NULL) {}
+
+               ~Scheduler()
+               {
+                       ctx_sched_destroy(__scheduler);
+               }
+
+               ctx_sched_h get()
+               {
+                       if (__scheduler == NULL)
+                               ctx_sched_create(&__scheduler);
+
+                       return __scheduler;
+               }
+       };
+}
+
+static OpType __getOpType(const char* opStr)
 {
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && rule_id);
+       if (STR_EQ(opStr, CONTEXT_TRIGGER_EQUAL_TO))
+               return OpType::EQ;
 
-       // Err: No event
-       if (!ctx::rule_util::isEventSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
+       if (STR_EQ(opStr, CONTEXT_TRIGGER_NOT_EQUAL_TO))
+               return OpType::NE;
 
-       // Err: No action
-       if (!ctx::rule_util::isActionSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
+       if (STR_EQ(opStr, CONTEXT_TRIGGER_GREATER_THAN))
+               return OpType::GT;
 
-       // 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);
-       }
+       if (STR_EQ(opStr, CONTEXT_TRIGGER_GREATER_THAN_OR_EQUAL_TO))
+               return OpType::GE;
 
-       ctx::CtxJson1 jrule_id;
-       int error = __dbusClient.write(SUBJ_TRIGGER_ADD, rule->jrule, &jrule_id);
+       if (STR_EQ(opStr, CONTEXT_TRIGGER_LESS_THAN))
+               return OpType::LT;
 
-       if (error == ERR_NONE) {
-               jrule_id.get(NULL, TRIG_KEY_RULE_ID, rule_id);
-       }
+       if (STR_EQ(opStr, CONTEXT_TRIGGER_LESS_THAN_OR_EQUAL_TO))
+               return OpType::LE;
+
+       return OpType::UNDEFINED;
+}
+
+static std::string __get_custom_uri(std::string name, std::string provider)
+{
+       std::string uri("http://");
+       uri += provider + "/context/custom/" + name;
+       return uri;
+}
+
+static const char* __get_pkg_id()
+{
+       static char pkgId[PKG_ID_LENGTH] = {0};
+
+       if (strlen(pkgId) > 0)
+               return pkgId;
+
+       aul_app_get_pkgid_bypid(getpid(), pkgId, PKG_ID_LENGTH);
+
+       if (strlen(pkgId) > 0)
+               return pkgId;
+
+       return NULL;
+}
+
+static ContextItem* __get_context_item(context_trigger_rule_entry_h entry)
+{
+       ContextItem* contextItem = NULL;
+
+       if (entry->category == CATEGORY_EVENT)
+               contextItem = new(std::nothrow) EventItem(entry->type);
+       else
+               contextItem = new(std::nothrow) ConditionItem(entry->type);
 
-       return error;
+       if (!contextItem)
+               _E_ALLOC;
+
+       return contextItem;
 }
 
-// Remove a rule
-SO_EXPORT int context_trigger_remove_rule(int rule_id)
+static Scheduler __scheduler;
+
+
+EXPORT_API int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id)
 {
-       _D("BEGIN");
+       INIT_SCHED;
+       ASSERT_NOT_NULL(rule && rule_id);
+
+       int err = ctx_sched_add_job(SCHED, rule->job, rule_id);
+
+       if (err == E_PARAM)
+               return E_INV_RULE;
+
+       return err;
+}
+
+EXPORT_API int context_trigger_remove_rule(int rule_id)
+{
+       INIT_SCHED;
        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);
+       int err = ctx_sched_remove_job(SCHED, rule_id);
 
-       if (error == ERR_ALREADY_STARTED) {     // Rule is still enabled.
+       if (err == E_RULE_ON)
                return CONTEXT_TRIGGER_ERROR_RULE_ENABLED;
-       } else if (error == ERR_NO_DATA) {
+       else if (err == E_PARAM)
                return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       }
 
-       return error;
+       return err;
 }
 
-// Enable a rule
-SO_EXPORT int context_trigger_enable_rule(int rule_id)
+EXPORT_API int context_trigger_enable_rule(int rule_id)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        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 err = ctx_sched_start_job(SCHED, 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) {
+       if (err == E_PARAM)
                return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       }
 
-       return error;
+       return err;
 }
 
-// Disable a rule
-SO_EXPORT int context_trigger_disable_rule(int rule_id)
+EXPORT_API int context_trigger_disable_rule(int rule_id)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        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);
+       int err = ctx_sched_stop_job(SCHED, rule_id);
 
-       if (error == ERR_NO_DATA) {
+       if (err == E_PARAM)
                return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       }
 
-       return error;
+       return err;
+}
+
+static bool __foreach_job_cb(ctx_sched_h scheduler, ctx_sched_job_h job, void *user_data)
+{
+       auto jobs = static_cast<std::vector<ctx_sched_job_h>*>(user_data);
+       jobs->push_back(job);
+       return true;
 }
 
-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)
+EXPORT_API 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");
+       INIT_SCHED;
        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);
+       std::vector<ctx_sched_job_h> jobs;
 
-       if (error != ERR_NONE) {
-               return error;
+       int err = ctx_sched_foreach_job(SCHED, __foreach_job_cb, &jobs);
+
+       if (err == E_NO_DATA) {
+               *enabled_rule_ids = NULL;
+               *enabled_rule_count = 0;
+               *disabled_rule_ids = NULL;
+               *disabled_rule_count = 0;
+               return E_NONE;
        }
 
-       // Enabled rules
-       int* e_arr = NULL;
-       *enabled_rule_count = data_read.getSize(NULL, TRIG_KEY_ENABLED_IDS);
+       IF_FAIL_RETURN(IS_SUCCESS(err), err);
 
-       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");
+       std::vector<int> startedJobIds;
+       std::vector<int> stoppedJobIds;
 
-               int id;
-               for (int i = 0; data_read.getAt(NULL, TRIG_KEY_ENABLED_IDS, i, &id); i++) {
-                       *(e_arr + i) = id;
-               }
+       for (auto& job : jobs) {
+               bool started = false;
+               int jobId = 0;
+
+               ctx_sched_job_is_started(job, &started);
+               ctx_sched_job_get_id(job, &jobId);
+               ctx_sched_job_destroy(job);
+
+               if (started)
+                       startedJobIds.push_back(jobId);
+               else
+                       stoppedJobIds.push_back(jobId);
        }
-       *enabled_rule_ids = e_arr;
 
-       // Disabled rules
-       int* d_arr = NULL;
-       *disabled_rule_count = data_read.getSize(NULL, TRIG_KEY_DISABLED_IDS);
+       *enabled_rule_count = startedJobIds.size();
 
-       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");
+       if (*enabled_rule_count > 0)
+               *enabled_rule_ids = static_cast<int*>(g_memdup(startedJobIds.data(), startedJobIds.size() * sizeof(int)));
+       else
+               *enabled_rule_ids = NULL;
 
-               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;
+       *disabled_rule_count = stoppedJobIds.size();
 
-       return error;
-}
+       if (*disabled_rule_count > 0)
+               *disabled_rule_ids = static_cast<int*>(g_memdup(stoppedJobIds.data(), stoppedJobIds.size() * sizeof(int)));
+       else
+               *disabled_rule_ids = NULL;
 
+       return E_NONE;
+}
 
-SO_EXPORT int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
+EXPORT_API int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        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);
+       ctx_sched_job_h job = NULL;
 
-       int req_id;
-       ctx::CtxJson1 data_read;
-       int error = __dbusClient.readSync(SUBJ_TRIGGER_GET, option, &req_id, &data_read);
+       int err = ctx_sched_get_job(SCHED, rule_id, &job);
 
-       if (error == ERR_NO_DATA) {
+       if (err == E_PARAM)
                return CONTEXT_TRIGGER_ERROR_RULE_NOT_EXIST;
-       } else if (error != ERR_NONE) {
-               return error;
-       }
+       else if (err != E_NONE)
+               return err;
 
-       *rule = new(std::nothrow) _context_trigger_rule_h();
-       (*rule)->jrule = data_read;
+       *rule = new(std::nothrow) _context_trigger_rule_h(job);
+       if (*rule == NULL) {
+               _E_ALLOC;
+               ctx_sched_job_destroy(job);
+               return E_NO_MEM;
+       }
 
-       return ERR_NONE;
+       return E_NONE;
 }
 
-// Rule creation
-SO_EXPORT int context_trigger_rule_create(context_trigger_logical_type_e logical_type, context_trigger_rule_h* rule)
+EXPORT_API 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;
-       }
+       IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
 
        *rule = new(std::nothrow) _context_trigger_rule_h();
-       (*rule)->jold_rule.set(NULL, OLD_TRIG_RULE_KEY_OPERATOR, logical_str);
+       ASSERT_ALLOC(*rule);
+       if ((*rule)->job == NULL) {
+               _E_ALLOC;
+               delete *rule;
+               return E_NO_MEM;
+       }
 
-       (*rule)->jrule.set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, logical_str);
+       ctx_sched_job_set_disjunction((*rule)->job, logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION);
+       ctx_sched_job_set_persistent((*rule)->job, true);
 
-       return ERR_NONE;
+       return E_NONE;
 }
 
-// Rule deletion
-SO_EXPORT int context_trigger_rule_destroy(context_trigger_rule_h rule)
+EXPORT_API int context_trigger_rule_destroy(context_trigger_rule_h rule)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        ASSERT_NOT_NULL(rule);
+
        delete rule;
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return E_NONE;
 }
 
-
-SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
+static int __set_event(context_trigger_rule_h rule, context_trigger_rule_entry_h event)
 {
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && entry);
+       IF_FAIL_RETURN(event->jobContext, E_PARAM);
+       IF_FAIL_RETURN_TAG(!rule->hasEvent, E_INV_RULE, _E, "The rule already has the event");
 
-       // 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);
+       EventItem contextItem(event->type);
+       IF_FAIL_RETURN_TAG(contextItem.isValid(event->jobContext), E_INV_RULE, _E, "Incomplete event");
 
-       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;
-               }
+       ctx_sched_job_context_h dup = ctx_sched_job_context_duplicate(event->jobContext);
+       ASSERT_ALLOC(dup);
 
-               // 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;
-               }
+       int err = ctx_sched_job_add_trigger(rule->job, dup);
+       if (IS_FAILED(err)) {
+               ctx_sched_job_context_destroy(dup);
+               return err;
+       }
 
-               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);
+       rule->hasEvent = true;
 
-                       // 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;
-                       }
+       return E_NONE;
+}
 
-                       // 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);
-                               }
-                       }
-               }
+static int __add_condition(context_trigger_rule_h rule, context_trigger_rule_entry_h condition)
+{
+       IF_FAIL_RETURN(condition->jobContext, E_PARAM);
 
-               ctx::CtxJson1 temp = (entry->jentry).str();
-               ret = (rule->jold_rule).append(NULL, OLD_TRIG_RULE_KEY_CONDITION, temp);
+       bool exist = (rule->conditions.find(condition->uri) != rule->conditions.end());
+       IF_FAIL_RETURN_TAG(!exist, E_INV_RULE, _E, "The same condition exists");
 
-               ctx::rule_util::addCondition(entry->jentry, &(rule->jrule));
-       } else {
-               // Entry is not created
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
+       ConditionItem contextItem(condition->type);
+       IF_FAIL_RETURN_TAG(contextItem.isValid(condition->jobContext), E_INV_RULE, _E, "Incomplete condition");
+
+       ctx_sched_job_context_h dup = ctx_sched_job_context_duplicate(condition->jobContext);
+       ASSERT_ALLOC(dup);
+
+       int err = ctx_sched_job_add_requirement(rule->job, dup);
+       if (IS_FAILED(err)) {
+               ctx_sched_job_context_destroy(dup);
+               return err;
        }
 
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return E_NONE;
 }
 
-static bool is_call_operation(app_control_h app_control)
+EXPORT_API int context_trigger_rule_add_entry(context_trigger_rule_h rule, context_trigger_rule_entry_h entry)
+{
+       ASSERT_NOT_NULL(rule && entry);
+       IF_FAIL_RETURN_TAG(!rule->readOnly, E_PARAM,
+                       _E, "A rule acquired by context_trigger_get_rule_by_id() is not allowed to be modified.");
+
+       if (entry->category == CATEGORY_EVENT)
+               return __set_event(rule, entry);
+       else
+               return __add_condition(rule, entry);
+}
+
+static bool __is_call_operation(app_control_h ctrl)
 {
        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");
+       int err = app_control_get_operation(ctrl, &op);
+       IF_FAIL_RETURN_TAG(err == APP_CONTROL_ERROR_NONE, false, _E, "Getting operation of app control failed");
 
        bool ret = STR_EQ(op, APP_CONTROL_OPERATION_CALL);
        g_free(op);
@@ -377,830 +460,500 @@ static bool is_call_operation(app_control_h app_control)
        return ret;
 }
 
-SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
+static bool __is_ui_app(app_control_h ctrl)
 {
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && app_control);
-       int error;
+       char* appId = NULL;
+       int err = app_control_get_app_id(ctrl, &appId);
 
-       // Privilege check
-       error = __dbusClient.call(METHOD_CHK_PRIV_APPLAUNCH);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+       IF_FAIL_RETURN_TAG(err == E_NONE, false, _E, "Failed to get the app id");
 
-       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);
-       }
+       pkgmgrinfo_appinfo_h appInfo;
+       err = pkgmgrinfo_appinfo_get_usr_appinfo(appId, getuid(), &appInfo);
+       g_free(appId);
+
+       IF_FAIL_RETURN_TAG(err == PMINFO_R_OK, false, _E, "No such app");
+
+       char *appType = NULL;
+       pkgmgrinfo_appinfo_get_component_type(appInfo, &appType);
 
-       // Err: if action arleady exists
-       if (ctx::rule_util::isActionSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       bool ret = STR_EQ(appType, "uiapp");
+
+       pkgmgrinfo_appinfo_destroy_appinfo(appInfo);
+
+       return ret;
+}
+
+EXPORT_API int context_trigger_rule_set_action_app_control(context_trigger_rule_h rule, app_control_h app_control)
+{
+       INIT_SCHED;
+       ASSERT_NOT_NULL(rule && app_control);
+
+       if (!PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/appmanager.launch")) {
+               _E("Privilege denied");
+               return E_ACCESS;
        }
 
-       // 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;
+       if (__is_call_operation(app_control) &&
+                       !PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/call")) {
+               _E("Privilege denied");
+               return E_ACCESS;
        }
-       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");
+       IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
+       IF_FAIL_RETURN_TAG(__is_ui_app(app_control), E_INV_RULE, _E, "Invalid app-control");
 
-       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");
+       bundle* bn = NULL;
+       app_control_export_as_bundle(app_control, &bn);
+       IF_FAIL_RETURN_TAG(bn, E_PARAM, _E, "Converting 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);
+       int ret = ctx_sched_job_set_app_control(rule->job, bn);
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       if (ret == E_NONE)
+               rule->hasAction = true;
+
+       return ret;
 }
 
-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)
+static bool __is_valid_app_control(app_control_h ctrl)
 {
-       _D("BEGIN");
-       ASSERT_NOT_NULL(rule && title && content);
+       if (!ctrl) return true;
 
-       // Privilege check
-       int error = __dbusClient.call(METHOD_CHK_PRIV_NOTIFICATION);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
+       char* appId = NULL;
+       int err = app_control_get_app_id(ctrl, &appId);
+       IF_FAIL_RETURN_TAG(err == E_NONE, false, _E, "Failed to get the app id");
 
-       // if action arleady exists
-       if (ctx::rule_util::isActionSet(rule->jrule)) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
+       pkgmgrinfo_appinfo_h appInfo;
+       err = pkgmgrinfo_appinfo_get_usr_appinfo(appId, getuid(), &appInfo);
+       g_free(appId);
+       IF_FAIL_RETURN_TAG(err == PMINFO_R_OK, false, _E, "No such app");
 
-       // 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(appInfo);
 
-               pkgmgrinfo_appinfo_destroy_appinfo(app_info);
-       }
+       return true;
+}
 
-       // 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);
+EXPORT_API 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)
+{
+       INIT_SCHED;
+       ASSERT_NOT_NULL(rule && title && 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);
+       if (!PrivilegeChecker::hasPrivilege("http://tizen.org/privilege/notification")) {
+               _E("Privilege denied");
+               return E_ACCESS;
        }
 
-       // 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");
+       IF_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
+       IF_FAIL_RETURN_TAG(__is_valid_app_control(app_control), E_INV_RULE, _E, "Invalid app-control");
 
-               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");
+       bundle* bn = NULL;
+       if (app_control) {
+               app_control_export_as_bundle(app_control, &bn);
+               IF_FAIL_RETURN_TAG(bn, E_PARAM, _E, "Converting 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);
+       int ret = ctx_sched_job_set_notification(rule->job, title, content, icon_path, bn);
 
-               bundle_free_encoded_rawdata(&appctl_raw);
-       }
+       if (ret == E_NONE)
+               rule->hasAction = true;
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return ret;
 }
 
 //LCOV_EXCL_START
-SO_EXPORT int context_trigger_rule_set_action_dbus_call(context_trigger_rule_h rule,
+EXPORT_API 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_FAIL_RETURN_TAG(!rule->hasAction, E_INV_RULE, _E, "The rule has an action");
 
-       /* 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);
+       int ret = ctx_sched_job_set_dbus(rule->job, bus_name, object_path, interface_name, method_name, param);
 
-       /* Set the parameters */
-       if (param)
-               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_PARAMETER, param);
+       if (ret == E_NONE)
+               rule->hasAction = true;
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return ret;
 }
 //LCOV_EXCL_STOP
 
-// Set description
-SO_EXPORT int context_trigger_rule_set_description(context_trigger_rule_h rule, const char* description)
+EXPORT_API 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);
+       ASSERT_NOT_NULL(rule && description);
+       IF_FAIL_RETURN(strlen(description) > 0, E_PARAM);
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return ctx_sched_job_set_user_data(rule->job, description, strlen(description) + 1);
 }
 
-// Get rule description
-SO_EXPORT int context_trigger_rule_get_description(context_trigger_rule_h rule, char** description)
+EXPORT_API 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);
+       char* val = NULL;
+       size_t len = 0;
+       int err = ctx_sched_job_get_user_data(rule->job, &val, &len);
+       IF_FAIL_RETURN(IS_SUCCESS(err), err);
+       IF_FAIL_RETURN(val, E_NONE);
 
-       *description = strdup(val.c_str());
+       *description = val;
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return E_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)
+EXPORT_API 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");
+       INIT_SCHED;
        ASSERT_NOT_NULL(entry);
+       IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
 
-       if (event_is_deprecated(event_item)) {
-               _W(TRIGGER_DEPRECATED_EVENT_MSG);
-       }
+       EventItem contextItem(event_item);
+       IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Event: %d", event_item);
 
-       std::string eitem_str = convert_event_to_string(event_item);
-       if (eitem_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
+       if (contextItem.deprecated())
+               _DEPRECATED_EVENT(event_item);
 
-       int error = context_trigger_rule_event_create_internal(eitem_str.c_str(), logical_type, entry);
-       return error;
-}
+       IF_FAIL_RETURN_TAG(contextItem.allowed(), E_ACCESS, _E, "Privilege denied");
 
-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);
+       bool supported = false;
+       ctx_sched_job_trigger_is_supported(SCHED, contextItem.getUri(), &supported);
+       IF_FAIL_RETURN_TAG(supported, E_SUPPORT, _E, "Event-%d is not supported", event_item);
 
-       // 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");
+       *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_EVENT, event_item, contextItem.getUri());
+       ASSERT_ALLOC(*entry);
 
-       std::string subject = get_custom_item_subject(provider, event_item);
-       error = context_trigger_rule_event_create_internal(subject.c_str(), logical_type, entry, true);
+       ctx_sched_job_context_set_disjunction((*entry)->jobContext, (logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION));
 
-       return error;
+       return E_NONE;
 }
 
-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)
+static bool __is_valid_pkg_id(const char* pkgId)
 {
-       _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;
-       }
+       IF_FAIL_RETURN(pkgId, false);
 
-       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);
+       pkgmgrinfo_pkginfo_h pkgInfo;
+       int err = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId, getuid(), &pkgInfo);
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkgInfo);
 
-       *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;
+       return (PMINFO_R_OK == err);
 }
 
-// Event availability check
-SO_EXPORT int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
+EXPORT_API 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(supported);
+       INIT_SCHED;
+       ASSERT_NOT_NULL(event_item && provider && entry);
+       IF_FAIL_RETURN_TAG(__is_valid_pkg_id(provider), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
 
-       if (event_is_deprecated(event_item)) {
-               _W(TRIGGER_DEPRECATED_EVENT_MSG);
-       }
+       std::string uri = __get_custom_uri(event_item, provider);
 
-       *supported = false;
+       bool registered = false;
+       ctx_sched_custom_is_registered(SCHED, uri.c_str(), provider, &registered);
+       IF_FAIL_RETURN_TAG(registered, E_SUPPORT, _W, "%s is not registered yet", event_item);
 
-       std::string eitem_str = convert_event_to_string(event_item);
-       if (eitem_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
+       *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_EVENT, 0, uri.c_str());
+       ASSERT_ALLOC(*entry);
 
-       int error = __dbusClient.isSupported(eitem_str);
+       return E_NONE;
+}
 
-       if (error == ERR_NONE)
-               *supported = true;
+EXPORT_API int context_trigger_rule_event_is_supported(context_trigger_event_e event_item, bool* supported)
+{
+       INIT_SCHED;
+       ASSERT_NOT_NULL(supported);
 
-       if (error == ERR_NOT_SUPPORTED)
-               return ERR_NONE;
+       EventItem contextItem(event_item);
+       IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Event: %d", event_item);
 
-       return error;
+       return ctx_sched_job_trigger_is_supported(SCHED, contextItem.getUri(), supported);
 }
 
-// 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)
+EXPORT_API 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");
+       INIT_SCHED;
        ASSERT_NOT_NULL(entry);
+       IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
 
-       if (condition_is_deprecated(condition_item)) {
-               _W(TRIGGER_DEPRECATED_CONDITION_MSG);
-       }
+       ConditionItem contextItem(condition_item);
+       IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Condition: %d", condition_item);
 
-       std::string citem_str = convert_condition_to_string(condition_item);
-       if (citem_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
+       if (contextItem.deprecated())
+               _DEPRECATED_COND(condition_item);
 
-       int error = context_trigger_rule_condition_create_internal(citem_str.c_str(), logical_type, entry);
-       return error;
-}
+       IF_FAIL_RETURN_TAG(contextItem.allowed(), E_ACCESS, _E, "Privilege denied");
 
-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);
+       bool supported = false;
+       ctx_sched_job_requirement_is_supported(SCHED, contextItem.getUri(), &supported);
+       IF_FAIL_RETURN_TAG(supported, E_SUPPORT, _E, "Condition-%d is not supported", condition_item);
 
-       // 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");
+       *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_CONDITION, condition_item, contextItem.getUri());
+       ASSERT_ALLOC(*entry);
 
-       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;
+       ctx_sched_job_context_set_disjunction((*entry)->jobContext, (logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION));
+
+       return E_NONE;
 }
 
-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)
+EXPORT_API 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);
+       INIT_SCHED;
+       ASSERT_NOT_NULL(condition_item && provider && entry);
+       IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
+       IF_FAIL_RETURN_TAG(__is_valid_pkg_id(provider), CONTEXT_TRIGGER_ERROR_INVALID_DATA, _E, "No such package");
 
-       std::string logical_str = convert_logical_type_to_string(logical_type);
-       if (logical_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
+       std::string uri = __get_custom_uri(condition_item, provider);
 
-       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);
+       bool registered = false;
+       ctx_sched_custom_is_registered(SCHED, uri.c_str(), provider, &registered);
+       IF_FAIL_RETURN_TAG(registered, E_SUPPORT, _W, "%s is not registered yet", condition_item);
 
-       *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);
+       *entry = new(std::nothrow) _context_trigger_rule_entry_h(CATEGORY_CONDITION, 0, uri.c_str());
+       ASSERT_ALLOC(*entry);
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return E_NONE;
 }
 
-// Condition availability check
-SO_EXPORT int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
+EXPORT_API int context_trigger_rule_condition_is_supported(context_trigger_condition_e condition_item, bool* supported)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        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;
+       ConditionItem contextItem(condition_item);
+       IF_FAIL_RETURN_TAG(contextItem.getUri(), E_PARAM, _E, "Unknown Condition: %d", condition_item);
 
-       if (error == ERR_NOT_SUPPORTED)
-               return ERR_NONE;
-
-       return error;
+       return ctx_sched_job_requirement_is_supported(SCHED, contextItem.getUri(), supported);
 }
 
-// Rule data deletion
-SO_EXPORT int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
+EXPORT_API int context_trigger_rule_entry_destroy(context_trigger_rule_entry_h entry)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        ASSERT_NOT_NULL(entry);
+
        delete entry;
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return E_NONE;
 }
 
-SO_EXPORT int context_trigger_rule_entry_add_option_int(context_trigger_rule_entry_h entry, const char* option_key, int value)
+EXPORT_API 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;
-       }
+       ContextItem* contextItem = __get_context_item(entry);
+       IF_FAIL_RETURN(contextItem, E_FAILED);
 
-       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
+       bool valid = contextItem->isValidOption(option_key, value);
+       delete contextItem;
+       IF_FAIL_RETURN(valid, E_INV_RULE);
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       ctx_sched_job_context_prepare_attribute_int(entry->jobContext, option_key);
+       return ctx_sched_job_context_attribute_add_eq_int(entry->jobContext, option_key, value);
 }
 
-SO_EXPORT int context_trigger_rule_entry_add_option_string(context_trigger_rule_entry_h entry, const char* option_key, const char* value)
+EXPORT_API 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__);
+       _DEPRECATED_FUNC;
        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;
-       }
+       ContextItem* contextItem = __get_context_item(entry);
+       IF_FAIL_RETURN(contextItem, E_FAILED);
 
-       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, value);
+       bool valid = contextItem->isValidOption(option_key, value);
+       delete contextItem;
+       IF_FAIL_RETURN(valid, E_INV_RULE);
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       ctx_sched_job_context_prepare_attribute_str(entry->jobContext, option_key);
+       return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, option_key, value);
 }
 
-SO_EXPORT int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h entry, const char* option_key, const char* event_data_key)
+EXPORT_API 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__);
+       _DEPRECATED_FUNC;
        ASSERT_NOT_NULL(entry && option_key && event_data_key);
+       IF_FAIL_RETURN(entry->category == CATEGORY_CONDITION, E_INV_RULE);
 
-       // 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);
+       ConditionItem contextItem(entry->type);
+       IF_FAIL_RETURN(contextItem.isValidOption(option_key), E_INV_RULE);
 
-       // 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);
+       ctx_sched_job_context_prepare_attribute_str(entry->jobContext, option_key);
+       return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, option_key, event_data_key);
+}
 
-       (entry->jentry).set(OLD_TRIG_RULE_KEY_CONDITION_OPTION, option_key, std::string(TRIG_RULE_REF_KEY_PREFIX) + std::string(event_data_key));
+static bool __is_member_key(context_trigger_rule_entry_h entry, const char* key)
+{
+       if (entry->attributes.find(key) != entry->attributes.end()) {
+               _D("'%s' found", key);
+               return true;
+       }
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       _D("'%s' not found", key);
+       return false;
 }
 
-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)
+EXPORT_API 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);
+       IF_FAIL_RETURN(logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION || logical_type == CONTEXT_TRIGGER_LOGICAL_DISJUNCTION, E_PARAM);
 
-       std::string logical_str = convert_logical_type_to_string(logical_type);
-       if (logical_str.empty()) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
-       }
+       ContextItem* contextItem = __get_context_item(entry);
+       IF_FAIL_RETURN(contextItem, E_FAILED);
 
-       // 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;
-               }
-       }
+       bool valid = contextItem->isValidData(key);
+       delete contextItem;
+       IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
+       IF_FAIL_RETURN(!__is_member_key(entry, key), E_INV_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);
+       entry->attributes.emplace(key, logical_type == CONTEXT_TRIGGER_LOGICAL_CONJUNCTION);
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
+       return E_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)
+EXPORT_API int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_h entry, const char* key, const char* op, const char* event_data_key)
 {
-       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);
+       _DEPRECATED_FUNC;
+       ASSERT_NOT_NULL(entry && key && op && event_data_key);
+       IF_FAIL_RETURN(entry->category == CATEGORY_CONDITION, E_INV_RULE);
 
-                       return CONTEXT_TRIGGER_ERROR_NONE;
-               }
-       }
+       ConditionItem contextItem(entry->type);
+       IF_FAIL_RETURN(contextItem.isValidData(key), E_INV_RULE);
+       IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
 
-       // Comparison key not exist
-       return CONTEXT_TRIGGER_ERROR_NO_DATA;
-}
+       ctx_sched_job_context_prepare_attribute_str(entry->jobContext, key);
 
-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);
+       if (__getOpType(op) == OpType::EQ)
+               return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, key, event_data_key);
 
-                       return CONTEXT_TRIGGER_ERROR_NONE;
-               }
-       }
+       if (__getOpType(op) == OpType::NE)
+               return ctx_sched_job_context_attribute_add_ne_str(entry->jobContext, key, event_data_key);
 
-       // Comparison key not exist
-       return CONTEXT_TRIGGER_ERROR_NO_DATA;
+       _E("Invalid operator");
+       return E_INV_RULE;
 }
 
-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)
+EXPORT_API int context_trigger_rule_entry_add_comparison_int(context_trigger_rule_entry_h entry, const char* key, const char* op, int value)
 {
-       _D("BEGIN");
-       _W(TRIGGER_DEPRECATED_FUNCTION_MSG, __FUNCTION__);
-       ASSERT_NOT_NULL(entry && key && op && event_data_key);
+       ASSERT_NOT_NULL(entry && key && op);
 
-       // Err: Only condition can reference data from event
-       if (entry->type != TYPE_CONDITION) {
-               return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-       }
+       ContextItem* contextItem = __get_context_item(entry);
+       IF_FAIL_RETURN(contextItem, E_FAILED);
 
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &name);
+       bool valid = contextItem->isValidData(key, value);
+       delete contextItem;
+       IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
+       IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
 
-       // 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);
+       ctx_sched_job_context_prepare_attribute_int(entry->jobContext, key);
 
-       // 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);
+       if (__getOpType(op) == OpType::EQ)
+               return ctx_sched_job_context_attribute_add_eq_int(entry->jobContext, key, value);
 
-       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);
+       if (__getOpType(op) == OpType::NE)
+               return ctx_sched_job_context_attribute_add_ne_int(entry->jobContext, key, value);
 
-       // 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);
+       _context_trigger_rule_entry_s::Bound& bound = entry->attributes.find(key)->second;
 
-       return CONTEXT_TRIGGER_ERROR_NONE;
-}
+       if (__getOpType(op) == OpType::GT) {
+               if (bound.conjunction) bound.gt = std::max(bound.gt, value);
+               else                   bound.gt = std::min(bound.gt, value);
+               return ctx_sched_job_context_attribute_set_gt_int(entry->jobContext, key, bound.gt);
+       }
 
-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);
+       if (__getOpType(op) == OpType::GE) {
+               if (bound.conjunction) bound.ge = std::max(bound.ge, value);
+               else                   bound.ge = std::min(bound.ge, value);
+               return ctx_sched_job_context_attribute_set_ge_int(entry->jobContext, key, bound.ge);
+       }
 
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+       if (__getOpType(op) == OpType::LT) {
+               if (bound.conjunction) bound.lt = std::min(bound.lt, value);
+               else                   bound.lt = std::max(bound.lt, value);
+               return ctx_sched_job_context_attribute_set_lt_int(entry->jobContext, key, bound.lt);
+       }
 
-       bool ret = ctx::rule_validator::check_comparison_int(name, key, op, value);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+       if (__getOpType(op) == OpType::LE) {
+               if (bound.conjunction) bound.le = std::min(bound.le, value);
+               else                   bound.le = std::max(bound.le, value);
+               return ctx_sched_job_context_attribute_set_le_int(entry->jobContext, key, bound.le);
+       }
 
-       int error = context_trigger_rule_entry_add_comparison_int_internal(entry, key, op, value);
-       return error;
+       _E("Invalid operator");
+       return E_INV_RULE;
 }
-/*
-SO_EXPORT int context_trigger_rule_entry_add_comparison_double(context_trigger_rule_entry_h entry, const char* key, const char* op, double value)
+
+EXPORT_API 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);
+       ASSERT_NOT_NULL(entry && key && op && value);
 
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+       ContextItem* contextItem = __get_context_item(entry);
+       IF_FAIL_RETURN(contextItem, E_FAILED);
 
-       // 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);
+       bool valid = contextItem->isValidData(key, value);
+       delete contextItem;
+       IF_FAIL_RETURN_TAG(valid, E_INV_RULE, _E, "Invalid parameter");
+       IF_FAIL_RETURN(__is_member_key(entry, key), E_NO_DATA);
 
-       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);
+       ctx_sched_job_context_prepare_attribute_str(entry->jobContext, key);
 
-       std::string name;
-       (entry->jentry).get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
+       if (__getOpType(op) == OpType::EQ)
+               return ctx_sched_job_context_attribute_add_eq_str(entry->jobContext, key, value);
 
-       bool ret = ctx::rule_validator::check_comparison_string(name, key, op, value);
-       IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
+       if (__getOpType(op) == OpType::NE)
+               return ctx_sched_job_context_attribute_add_ne_str(entry->jobContext, key, value);
 
-       int error = context_trigger_rule_entry_add_comparison_string_internal(entry, key, op, value);
-       return error;
+       _E("Invalid operator");
+       return E_INV_RULE;
 }
 
-SO_EXPORT int context_trigger_custom_register(const char* name, const char* attr_template)
+EXPORT_API int context_trigger_custom_register(const char* name, const char* attr_template)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        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");
+       int error = CustomTemplate::add(name, attr_template);
+       IF_FAIL_RETURN_TAG(error == E_NONE, error, _E, "Failed to add 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");
+       const char* pkgId = __get_pkg_id();
+       IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
 
-       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);
+       std::string uri = __get_custom_uri(name, pkgId);
 
-       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);
+       int err = ctx_sched_custom_register(SCHED, uri.c_str());
+       IF_FAIL_RETURN(err == E_NONE, E_FAILED);
 
-       return error;
+       return E_NONE;
 }
 
-SO_EXPORT int context_trigger_custom_unregister(const char* name)
+EXPORT_API int context_trigger_custom_unregister(const char* name)
 {
-       _D("BEGIN");
+       INIT_SCHED;
        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);
+       CustomTemplate* customTemplate = CustomTemplate::get(name);
+       IF_FAIL_RETURN_TAG(customTemplate, E_SUPPORT, _E, "Unknown custom 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);
+       CustomTemplate::remove(name);
 
-       std::string subject;
-       subj.get(NULL, TRIG_TMPL_KEY_SUBJECT, &subject);
-       ctx::rule_validator::remove_template(subject);
+       const char* pkgId = __get_pkg_id();
+       IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
 
-       return error;
-}
+       std::string uri = __get_custom_uri(name, pkgId);
 
-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);
+       ctx_sched_custom_unregister(SCHED, uri.c_str());
 
-       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;
+       return E_NONE;
 }
 
-std::string convert_event_to_string(context_trigger_event_e item)
+EXPORT_API int context_trigger_custom_publish(const char* name, const char* fact)
 {
-       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;
-}
+       INIT_SCHED;
+       ASSERT_NOT_NULL(name && fact);
 
-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;
-}
+       CustomTemplate* customTemplate = CustomTemplate::get(name);
+       IF_FAIL_RETURN_TAG(customTemplate, E_SUPPORT, _E, "Unknown custom name");
 
-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;
-}
+       int error = customTemplate->match(fact);
+       IF_FAIL_RETURN_TAG(error == E_NONE, error, _E, "Failed to publish fact");
 
-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;
-}
+       const char* pkgId = __get_pkg_id();
+       IF_FAIL_RETURN_TAG(pkgId, E_SUPPORT, _E, "PkgId is required");
 
-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 uri = __get_custom_uri(name, pkgId);
 
-/*
-std::string int_to_string(int value)
-{
-       std::ostringstream ostr;
-       ostr << value;
-       return ostr.str();
+       return ctx_sched_publish_context_json(SCHED, uri.c_str(), fact);
 }
-
-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
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/trigger/rule_validator.cpp b/src/trigger/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/trigger/rule_validator.h b/src/trigger/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__ */