2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <TriggerRuleTypes.h>
19 #include "ActionManager.h"
20 #include "RuleEvaluator.h"
21 #include "ContextMonitor.h"
22 #include "FactTypes.h"
23 #include "RuleManager.h"
26 using namespace ctx::trigger;
28 RuleManager *Rule::__ruleMgr = NULL;
30 Rule::Rule(int i, Json& d, const char* p, RuleManager* rm) :
31 __result(EMPTY_JSON_OBJECT),
41 __statement = d.str();
45 d.get(NULL, TRIG_RULE_KEY_EVENT, &e);
46 __event = new(std::nothrow) ContextItem(e);
49 int condNum = d.getSize(NULL, TRIG_RULE_KEY_CONDITION);
50 for (int j = 0; j < condNum; j++) {
52 d.getAt(NULL, TRIG_RULE_KEY_CONDITION, j, &c);
53 __condition.push_back(new(std::nothrow) ContextItem(c));
58 d.get(NULL, _TRIG_RULE_KEY_EXTRA, &extra);
59 __extra = extra.str();
63 d.get(NULL, TRIG_RULE_KEY_ACTION, &a);
71 for (auto it = __condition.begin(); it != __condition.end(); ++it) {
79 int error = ContextMonitor::getInstance()->subscribe(id, __event->name, __event->option, this);
80 IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to start rule%d", id);
88 int error = ContextMonitor::getInstance()->unsubscribe(id, __event->name, __event->option, this);
89 if (error == ERR_NOT_SUPPORTED) {
90 _E("Stop rule%d (event not supported)");
93 IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id);
98 bool Rule::__setConditionOptionBasedOnEvent(Json& option)
100 // Set condition option if it references event data
101 std::list<std::string> optionKeys;
102 option.getKeys(&optionKeys);
104 for (auto it = optionKeys.begin(); it != optionKeys.end(); ++it) {
105 std::string optKey = (*it);
108 if (option.get(NULL, optKey.c_str(), &optVal)) {
109 if (optVal.find("?") != 0) {
113 std::string eventKey = optVal.substr(1, optVal.length() - 1);
117 if (__result.get(FACT_KEY_EVENT "." FACT_KEY_DATA, eventKey.c_str(), &newStr)) {
118 option.set(NULL, optKey.c_str(), newStr);
119 } else if (__result.get(FACT_KEY_EVENT "." FACT_KEY_DATA, eventKey.c_str(), &new_val)) {
120 option.set(NULL, optKey.c_str(), new_val);
122 _W("Failed to find '%s' in event data", eventKey.c_str());
131 void Rule::onEventReceived(std::string name, Json option, Json data)
133 if (__result != EMPTY_JSON_OBJECT) {
137 // Check if creator package is uninstalled
138 if (RuleManager::isUninstalledPackage(pkgId)) {
139 _D("Creator(%s) of rule%d is uninstalled.", pkgId.c_str(), id);
140 g_idle_add(__handleUninstalledRule, &pkgId);
144 _D("Rule%d received event data", id);
147 __result.set(FACT_KEY_EVENT, FACT_KEY_NAME, name);
148 __result.set(FACT_KEY_EVENT, FACT_KEY_OPTION, option);
149 __result.set(FACT_KEY_EVENT, FACT_KEY_DATA, data);
151 if (__condition.size() == 0) {
152 __onContextDataPrepared();
156 IF_FAIL_VOID_TAG(RuleEvaluator::evaluateRule(__statement, __result), _E, "Event not matched");
158 // Request read conditions
159 for (auto it = __condition.begin(); it != __condition.end(); ++it) {
160 Json condOption = (*it)->option.str();
161 if (!__setConditionOptionBasedOnEvent(condOption)) { // condOption should be copy of original option.
166 int error = ContextMonitor::getInstance()->read((*it)->name.c_str(), condOption, this);
167 IF_FAIL_VOID_TAG(error == ERR_NONE, _E, "Failed to read condition");
173 void Rule::onConditionReceived(std::string name, Json option, Json data)
175 _D("Rule%d received condition data", id);
177 // Set condition data
179 item.set(NULL, FACT_KEY_NAME, name);
180 item.set(NULL, FACT_KEY_OPTION, option);
181 item.set(NULL, FACT_KEY_DATA, data);
182 __result.append(NULL, FACT_KEY_CONDITION, item);
184 if (__result.getSize(NULL, FACT_KEY_CONDITION) == (int) __condition.size()) {
185 __onContextDataPrepared();
189 void Rule::__clearResult()
191 __result = EMPTY_JSON_OBJECT;
195 void Rule::__onContextDataPrepared(void)
197 if (RuleEvaluator::evaluateRule(__statement, __result)) {
198 action_manager::triggerAction(__action, pkgId);
203 gboolean Rule::__handleUninstalledRule(gpointer data)
205 std::string* pkgId = static_cast<std::string*>(data);
206 __ruleMgr->handleRuleOfUninstalledPackage(*pkgId);