4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
25 #include <types_internal.h>
26 #include <context_trigger_types_internal.h>
27 #include "script_generator.h"
28 #include "timer_types.h"
30 #define EVENT_WEEKDAY "(or (eq ?DayOfWeek \"Mon\") (eq ?DayOfWeek \"Tue\") (eq ?DayOfWeek \"Wed\") (eq ?DayOfWeek \"Thu\") (eq ?DayOfWeek \"Fri\"))"
31 #define EVENT_WEEKEND "(or (eq ?DayOfWeek \"Sat\") (eq ?DayOfWeek \"Sun\"))"
32 #define CONDITION_WEEKDAY "(or (eq (send [%s] get-DayOfWeek) \"Mon\") (eq (send [%s] get-DayOfWeek) \"Tue\") (eq (send [%s] get-DayOfWeek) \"Wed\") (eq (send [%s] get-DayOfWeek) \"Thu\") (eq (send [%s] get-DayOfWeek) \"Fri\"))"
33 #define CONDITION_WEEKEND "(or (eq (send [%s] get-DayOfWeek) \"Sat\") (eq (send [%s] get-DayOfWeek) \"Sun\"))"
35 static std::string generate_initial_fact(ctx::json event_template, ctx::json option);
36 static std::string generate_event_data(ctx::json event);
37 static std::string generate_condition_data(std::string rule_id, ctx::json conditions, std::string rule_op, ctx::json* inst_names);
39 static std::string int_to_string(int i)
41 std::ostringstream convert;
43 std::string str = convert.str();
47 static std::string convert_condition_weekday_weekend(std::string inst_name, std::string day)
49 std::string buf = (day.compare(TIMER_WEEKDAY) == 0)? CONDITION_WEEKDAY : CONDITION_WEEKEND;
52 while((pos = buf.find("%s", pos)) != std::string::npos) {
53 buf.replace(pos, 2, inst_name);
54 pos += inst_name.length();
60 std::string ctx::script_generator::generate_deftemplate(ctx::json* item)
65 item->get(NULL, "name", &name);
67 std::set<std::string> slot;
70 for (int i = 0; item->get_array_elem(NULL, "option", i, &opt_name); i++) {
71 slot.insert(opt_name);
74 std::string attr_name;
75 for (int i = 0; item->get_array_elem(NULL, "attributes", i, &attr_name); i++) {
76 slot.insert(attr_name);
79 //template name is "itemname"
80 script = "(deftemplate ";
84 for (std::set<std::string>::iterator it = slot.begin(); it != slot.end(); ++it){
87 script += " (default null))";
91 // _D("Deftemplate script is generated: %s", script.c_str());
97 std::string ctx::script_generator::generate_defclass(ctx::json* item)
102 item->get(NULL, "name", &name);
104 //class name is "C.itemname"
105 script = "(defclass C.";
107 script += " (is-a USER) (role concrete) ";
109 std::string attr_name;
110 for (int i = 0; item->get_array_elem(NULL, "attributes", i, &attr_name); i++) {
113 script += " (create-accessor read-write))";
117 // _D("Defclass script is generated: %s", script.c_str());
123 std::string ctx::script_generator::generate_makeinstance(ctx::json* item)
128 item->get(NULL, "name", &name);
130 std::string instance_name;
131 if (!item->get(NULL, "instance_name", &instance_name)) {
132 instance_name = name;
135 //instance name is "[itemname]"
137 script += instance_name;
141 std::string attr_name;
142 for (int i = 0; item->get_array_elem(NULL, "attributes", i, &attr_name); i++) {
149 // _D("Makeinstance script is generated: %s", script.c_str());
155 std::string ctx::script_generator::generate_undefrule(std::string rule_id)
158 script = "(undefrule rule";
165 std::string ctx::script_generator::generate_defrule(std::string rule_id, ctx::json event_template, ctx::json rule, ctx::json* inst_names, std::string zone)
168 ctx::json option = NULL;
169 rule.get(CT_RULE_EVENT, CT_RULE_EVENT_OPTION, &option);
171 script = "(defrule rule";
175 script += generate_initial_fact(event_template, option);
178 int eventdata_num = rule.array_get_size(CT_RULE_EVENT, CT_RULE_DATA_ARR);
179 int condition_num = rule.array_get_size(NULL, CT_RULE_CONDITION);
181 if (condition_num > 0) {
182 // case1: condition exists
183 script += "(if (and (eq ?*zone* \"";
187 if (eventdata_num > 0) {
189 rule.get(NULL, CT_RULE_EVENT, &event);
190 script += generate_event_data(event);
194 ctx::json conditions;
195 rule.get(NULL, CT_RULE_CONDITION, &conditions);
197 rule.get(NULL, CT_RULE_OPERATOR, &rule_op);
198 script += generate_condition_data(rule_id, conditions, rule_op, inst_names);
202 script += " (execute_action rule";
205 } else if (eventdata_num > 0) {
206 // case2: no conditions, but event data
208 rule.get(NULL, CT_RULE_EVENT, &event);
210 script += "(if (and (eq ?*zone* \"";
213 script += generate_event_data(event);
215 script += " (execute_action rule";
219 // case3: only action
220 script += "if (eq ?*zone* \"";
222 script += "\") then (execute_action rule";
228 _D("Defrule script generated: %s", script.c_str());
232 std::string generate_initial_fact(ctx::json event_template, ctx::json option)
234 std::string script = "(";
236 event_template.get(NULL, "name", &e_name);
243 for (int i = 0; event_template.get_array_elem(NULL, "option", i, &opt_key); i++) {
250 if (option.get(NULL, opt_key.c_str(), &val_str)) {
252 } else if (option.get(NULL, opt_key.c_str(), &val)) {
253 script += int_to_string(val);
264 for (int i = 0; event_template.get_array_elem(NULL, "attributes", i, &attr); i++) {
273 // _D("Initial event fact is %s", script.c_str());
277 std::string generate_event_data(ctx::json event)
280 event.get(NULL, CT_RULE_EVENT_ITEM, &ename);
283 int edata_count = event.array_get_size(NULL, CT_RULE_DATA_ARR);
285 if (edata_count > 1) {
287 event.get(NULL, CT_RULE_EVENT_OPERATOR, &item_op);
294 for (int i = 0; event.get_array_elem(NULL, CT_RULE_DATA_ARR, i, &edata); i++) {
295 std::string key_name;
296 if (ename.compare(TIMER_EVENT_SUBJECT) == 0) {
297 edata.get(NULL, CT_RULE_DATA_KEY, &key_name);
300 int valuecount = edata.array_get_size(NULL, CT_RULE_DATA_VALUE_ARR);
301 int opcount = edata.array_get_size(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
303 edata.get(NULL, CT_RULE_DATA_KEY, &key);
305 if (valuecount != opcount) {
306 _E("Invalid event data. (Value count:%d, Operator count: %d)", valuecount, opcount);
310 if (valuecount > 1) {
314 edata.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &key_op);
319 for (int j = 0; j < valuecount; j++){
322 edata.get_array_elem(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, j, &val_op);
323 edata.get_array_elem(NULL, CT_RULE_DATA_VALUE_ARR, j, &val);
325 if (key_name.compare(TIMER_RESPONSE_KEY_DAY_OF_WEEK) == 0) {
326 if (val.compare("\"" TIMER_WEEKDAY "\"") == 0) {
327 script += (val_op.compare("eq") == 0)? EVENT_WEEKDAY : EVENT_WEEKEND;
329 } else if (val.compare("\"" TIMER_WEEKEND "\"") == 0) {
330 script += (val_op.compare("eq") == 0)? EVENT_WEEKEND : EVENT_WEEKDAY;
344 if (valuecount > 1) {
349 if (edata_count > 1) {
356 std::string generate_condition_data(std::string rule_id, ctx::json conditions, std::string rule_op, ctx::json* inst_names)
361 conds.set(NULL, CT_RULE_CONDITION, conditions);
363 int conds_count = conds.array_get_size(NULL, CT_RULE_CONDITION);
364 if (conds_count > 1) {
366 script += rule_op; // operator between each condition item
371 for (int i = 0; conds.get_array_elem(NULL, CT_RULE_CONDITION, i, &it); i++) {
372 std::string cond_name;
373 it.get(NULL, CT_RULE_CONDITION_ITEM, &cond_name);
375 std::string inst_name;
376 (inst_names)->get(NULL, cond_name.c_str(), &inst_name);
378 int data_count = it.array_get_size(NULL, CT_RULE_DATA_ARR);
380 if (data_count > 1) {
382 it.get(NULL, CT_RULE_CONDITION_OPERATOR, &item_op);
384 script += item_op; // operator between data keys of a condition item
389 for (int j = 0; it.get_array_elem(NULL, CT_RULE_DATA_ARR, j, &data); j++) {
390 std::string key_name;
391 data.get(NULL, CT_RULE_DATA_KEY, &key_name);
392 int dval_count = data.array_get_size(NULL, CT_RULE_DATA_VALUE_ARR);
393 int dvalop_count = data.array_get_size(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
395 if (dval_count != dvalop_count) {
396 _E("Invalid condition data. (Data value count %d, Data value operator count %d)", dval_count, dvalop_count);
399 if (dval_count > 1) {
401 data.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &dkey_op);
404 script += dkey_op; // operator between comparison data values of a condition data key
408 for (int k = 0; k < dval_count; k++) {
411 data.get_array_elem(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, k, &dval_op);
412 data.get_array_elem(NULL, CT_RULE_DATA_VALUE_ARR, k, &dval);
414 if (inst_name.compare(TIMER_CONDITION_SUBJECT) == 0 && key_name.compare(TIMER_RESPONSE_KEY_DAY_OF_WEEK) == 0) {
415 if (dval.compare("\"" TIMER_WEEKDAY "\"") == 0) {
416 script += convert_condition_weekday_weekend(inst_name, (dval_op.compare("eq") == 0)? TIMER_WEEKDAY : TIMER_WEEKEND);
418 } else if (dval.compare("\"" TIMER_WEEKEND "\"") == 0) {
419 script += convert_condition_weekday_weekend(inst_name, (dval_op.compare("eq") == 0)? TIMER_WEEKEND : TIMER_WEEKDAY);
426 script += " (send [";
435 if (dval_count > 1) {
440 if (data_count > 1 ) {
445 if (conds_count > 1) {
452 std::string ctx::script_generator::generate_fact(std::string item_name, ctx::json event_template, ctx::json option, ctx::json data)
454 // Generate Fact script for invoked event
455 std::string script = "(";
464 for (int i = 0; event_template.get_array_elem(NULL, "option", i, &opt_key); i++) {
468 if (option.get(NULL, opt_key.c_str(), &val_str)) { // string type data
470 } else if (option.get(NULL, opt_key.c_str(), &value)) { // integer type data
471 script += int_to_string(value);
478 for (int i = 0; event_template.get_array_elem(NULL, "attributes", i, &key); i++) {
482 if (data.get(NULL, key.c_str(), &val_str)) { // string type data
483 script += "\"" + val_str + "\"";
484 } else if (data.get(NULL, key.c_str(), &value)) { // integer type data
485 script += int_to_string(value);
496 std::string ctx::script_generator::generate_modifyinstance(std::string instance_name, ctx::json condition_template, ctx::json data)
498 std::string script = "(modify-instance [";
499 script += instance_name;
505 for (int i = 0; condition_template.get_array_elem(NULL, "attributes", i, &key); i++) {
506 if (data.get(NULL, key.c_str(), &val_str)) { // string type data
507 script += "(" + key + " \"" + val_str + "\")";
508 } else if (data.get(NULL, key.c_str(), &value)) { // integer type data
509 script += "(" + key + " " + int_to_string(value) + ")";