Rule validation changed 85/56585/1
authorSomin Kim <somin926.kim@samsung.com>
Mon, 11 Jan 2016 09:08:16 +0000 (18:08 +0900)
committerSomin Kim <somin926.kim@samsung.com>
Mon, 11 Jan 2016 09:08:16 +0000 (18:08 +0900)
- _event_create(), condition_create() will return NOT_SUPPORTED
- Only needed template information will be requested
- Removed integer type of attribute/option definition

Change-Id: I619c09cdbb89dec4ef6af223228c0aa41de1fb66
Signed-off-by: Somin Kim <somin926.kim@samsung.com>
include/context_trigger.h
include/context_trigger_types_internal.h
src/context_trigger.cpp
src/rule_info.h [deleted file]
src/rule_validator.cpp
src/rule_validator.h

index 625a317..e259786 100644 (file)
@@ -883,6 +883,7 @@ int context_trigger_rule_get_description(context_trigger_rule_h rule, char** des
  * @retval             #CONTEXT_TRIGGER_ERROR_NONE                                     Successful
  * @retval             #CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER        Invalid parameter
  * @retval             #CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY            Memory allocation failed
+ * @retval             #CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED            Unsupported event contained
  *
  * @see                        context_trigger_rule_entry_destroy()
  */
@@ -917,6 +918,7 @@ int context_trigger_rule_event_is_supported(context_trigger_event_e event_item,
  * @retval             #CONTEXT_TRIGGER_ERROR_NONE                                     Successful
  * @retval             #CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER        Invalid parameter
  * @retval             #CONTEXT_TRIGGER_ERROR_OUT_OF_MEMORY            Memory allocation failed
+ * @retval             #CONTEXT_TRIGGER_ERROR_NOT_SUPPORTED            Unsupported condition contained
  *
  * @see                        context_trigger_rule_entry_destroy()
  */
index 6509245..13fb60b 100644 (file)
@@ -23,6 +23,7 @@
 #define CONTEXT_TRIGGER_SUBJECT_DISABLE "trigger/disable"
 #define CONTEXT_TRIGGER_SUBJECT_GET "trigger/get"
 #define CONTEXT_TRIGGER_SUBJECT_GET_RULE_IDS "trigger/get_rule_ids"
+#define CONTEXT_TRIGGER_SUBJECT_GET_TEMPLATE "trigger/tepmlate/get"
 
 #define CT_RULE_ARRAY_ENABLED "ARRAY_ENABLED"
 #define CT_RULE_ARRAY_DISABLED "ARRAY_DISABLED"
 #define TYPE_EVENT 1
 #define TYPE_CONDITION 2
 
-#define TYPE_OPTION 1
-#define TYPE_ATTR 2
-
 #define TYPE_INT_STR "integer"
 #define TYPE_STRING_STR "string"
 #define TYPE_DOUBLE_STR "double"
 
-#define TYPE_OPTION_STR "option"
+#define TYPE_OPTION_STR "options"
 #define TYPE_ATTR_STR "attributes"
+#define SUBJECT_STR "subject"
 
 
 #endif /* __TIZEN_CONTEXT_CONTEXT_TRIGGER_TYPES_INTERNAL_H__ */
index ea61c6e..b185ef4 100644 (file)
@@ -532,6 +532,9 @@ EXTAPI int context_trigger_rule_event_create(context_trigger_event_e event_item,
                return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
        }
 
+       int error = ctx::rule_validator::request_template(eitem_str);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
+
        *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_EVENT);
        (*entry)->jentry.set(NULL, CT_RULE_EVENT_ITEM, eitem_str);
        (*entry)->jentry.set(NULL, CT_RULE_EVENT_OPERATOR, logical_str);
@@ -579,6 +582,9 @@ EXTAPI int context_trigger_rule_condition_create(context_trigger_condition_e con
                return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
        }
 
+       int error = ctx::rule_validator::request_template(citem_str);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to request template: %#x", error);
+
        *entry = new(std::nothrow) _context_trigger_rule_entry_h(TYPE_CONDITION);
        (*entry)->jentry.set(NULL, CT_RULE_CONDITION_ITEM, citem_str);
        (*entry)->jentry.set(NULL, CT_RULE_CONDITION_OPERATOR, logical_str);
@@ -670,11 +676,11 @@ EXTAPI int context_trigger_rule_entry_add_option(context_trigger_rule_entry_h en
        (entry->jentry).get(NULL, CT_RULE_CONDITION_ITEM, &name);
 
        // Err: Check if key is valid
-       bool ret = ctx::rule_validator::check_valid_key(TYPE_OPTION, name, option_key);
+       bool ret = ctx::rule_validator::check_valid_key(TYPE_OPTION_STR, 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);
+       ret = ctx::rule_validator::set_ref_info(TYPE_OPTION_STR, &(entry->jref), name, option_key, event_data_key);
        IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
 
        (entry->jentry).set(CT_RULE_CONDITION_OPTION, option_key, EVENT_DATA_KEY_PREFIX_STR + std::string(event_data_key));
@@ -695,7 +701,7 @@ EXTAPI int context_trigger_rule_entry_add_key(context_trigger_rule_entry_h entry
        // Err: Check if key is valid
        std::string name;
        (entry->jentry).get(NULL, CT_RULE_EVENT_ITEM, &name);
-       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTR, name, key);
+       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTR_STR, name, key);
        IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
 
        ctx::json elem;
@@ -790,11 +796,11 @@ EXTAPI int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_
        (entry->jentry).get(NULL, CT_RULE_CONDITION_ITEM, &name);
 
        // Err: Check if key is valid
-       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTR, name, key);
+       bool ret = ctx::rule_validator::check_valid_key(TYPE_ATTR_STR, name, key);
        IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
 
        // Err: Invalid operator
-       std::string type = ctx::rule_validator::get_data_type(TYPE_ATTR, name, key);
+       std::string type = ctx::rule_validator::get_data_type(TYPE_ATTR_STR, name, key);
        ret = ctx::rule_validator::is_valid_operator(type, op);
        IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
 
@@ -802,7 +808,7 @@ EXTAPI int context_trigger_rule_entry_add_comparison(context_trigger_rule_entry_
        IF_FAIL_RETURN(error == ERR_NONE, error);
 
        // Set reference information
-       ret = ctx::rule_validator::set_ref_info(TYPE_ATTR, &(entry->jref), name, key, event_data_key);
+       ret = ctx::rule_validator::set_ref_info(TYPE_ATTR_STR, &(entry->jref), name, key, event_data_key);
        IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_OPERATION_FAILED);
 
        return CONTEXT_TRIGGER_ERROR_NONE;
diff --git a/src/rule_info.h b/src/rule_info.h
deleted file mode 100644 (file)
index 3e84945..0000000
+++ /dev/null
@@ -1,117 +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_INFO_H__
-#define __CONTEXT_RULE_INFO_H__
-
-#define RULE_INFO "{ \"templates\": [\
-               {\
-                       \"name\": \"device/alarm\",\
-                       \"attributes\": [ { \"key\": \"TimeOfDay\", \"type\": \"integer\", \"min\": 0, \"max\": 1439}, { \"key\": \"DayOfWeek\", \"type\": \"string\", \"values\": [ \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\", \"Weekday\", \"Weekend\" ] } ]\
-               },\
-               {\
-                       \"name\": \"device/time\",\
-                       \"attributes\": [ { \"key\": \"TimeOfDay\", \"type\": \"integer\", \"min\": 0, \"max\": 1439}, { \"key\": \"DayOfWeek\", \"type\": \"string\", \"values\": [ \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\", \"Weekday\", \"Weekend\" ] }, { \"key\" : \"DayOfMonth\", \"type\": \"integer\", \"min\": 1, \"max\": 31} ]\
-               },\
-               {\
-                       \"name\": \"system/battery\",\
-                       \"attributes\": [ { \"key\" : \"Level\", \"type\": \"string\", \"values\": [ \"Empty\", \"Critical\", \"Low\", \"Normal\", \"High\", \"Full\" ] }, { \"key\": \"IsCharging\", \"type\": \"integer\", \"min\": 0, \"max\": 1 } ]\
-               },\
-               {\
-                       \"name\": \"system/charger\",\
-                       \"attributes\": [ { \"key\": \"IsConnected\", \"type\": \"integer\", \"min\": 0, \"max\": 1 } ]\
-               },\
-               {\
-                       \"name\": \"system/gps\",\
-                       \"attributes\": [ { \"key\" : \"State\", \"type\": \"string\", \"values\": [ \"Disabled\", \"Searching\", \"Connected\" ] } ]\
-               },\
-               {\
-                       \"name\": \"system/headphone\",\
-                       \"attributes\": [{ \"key\": \"IsConnected\", \"type\": \"integer\", \"min\": 0, \"max\": 1 }, { \"key\": \"Type\", \"type\": \"string\", \"values\": [ \"Normal\", \"Headset\", \"Bluetooth\" ] } ]\
-               },\
-               {\
-                       \"name\": \"system/psmode\",\
-                       \"attributes\": [ { \"key\": \"IsEnabled\", \"type\": \"integer\", \"min\": 0, \"max\": 1 } ]\
-               },\
-               {\
-                       \"name\": \"system/usb\",\
-                       \"attributes\": [ { \"key\": \"IsConnected\", \"type\": \"integer\", \"min\": 0, \"max\": 1 } ]\
-               },\
-               {\
-                       \"name\": \"system/wifi\",\
-                       \"attributes\": [ { \"key\" : \"State\", \"type\": \"string\", \"values\": [ \"Disabled\", \"Unconnected\", \"Connected\" ] }, { \"key\": \"BSSID\", \"type\": \"string\", \"values\": [ ] } ]\
-               },\
-               {\
-                       \"name\": \"social/call\",\
-                       \"attributes\": [ { \"key\" : \"Medium\", \"type\": \"string\", \"values\": [ \"Voice\", \"Video\" ] }, { \"key\" : \"State\", \"type\": \"string\", \"values\": [ \"Idle\", \"Connecting\", \"Connected\" ] }, { \"key\": \"Address\", \"type\": \"string\", \"values\": [ ] } ]\
-               },\
-               {\
-                       \"name\": \"social/email\",\
-                       \"attributes\": [ { \"key\": \"Event\", \"type\": \"string\", \"values\": [ \"Received\", \"Sent\" ] } ]\
-               },\
-               {\
-                       \"name\": \"social/message\",\
-                       \"attributes\": [ { \"key\": \"Event\", \"type\": \"string\", \"values\": [ \"Received\" ] } , { \"key\": \"Type\", \"type\": \"string\", \"values\": [ \"SMS\", \"MMS\" ] }, { \"key\": \"Address\", \"type\": \"string\", \"values\": [ ] } ]\
-               },\
-               {\
-                       \"name\": \"activity/stationary\",\
-                       \"attributes\": [ { \"key\": \"Event\", \"type\": \"string\", \"values\": [ \"Detected\" ] }, { \"key\": \"Accuracy\", \"type\": \"string\", \"values\": [ \"High\", \"Normal\", \"Low\" ] } ]\
-               },\
-               {\
-                       \"name\": \"activity/walking\",\
-                       \"attributes\": [ { \"key\": \"Event\", \"type\": \"string\", \"values\": [ \"Detected\" ] }, { \"key\": \"Accuracy\", \"type\": \"string\", \"values\": [ \"High\", \"Normal\", \"Low\" ] } ]\
-               },\
-               {\
-                       \"name\": \"activity/running\",\
-                       \"attributes\": [ { \"key\": \"Event\", \"type\": \"string\", \"values\": [ \"Detected\" ] }, { \"key\": \"Accuracy\", \"type\": \"string\", \"values\": [ \"High\", \"Normal\", \"Low\" ] } ]\
-               },\
-               {\
-                       \"name\": \"activity/in_vehicle\",\
-                       \"attributes\": [ { \"key\": \"Event\", \"type\": \"string\", \"values\": [ \"Detected\" ] }, { \"key\": \"Accuracy\", \"type\": \"string\", \"values\": [ \"High\", \"Normal\", \"Low\" ] } ]\
-               },\
-               {\
-                       \"name\": \"place/geofence\",\
-                       \"attributes\": [ { \"key\": \"Event\", \"type\": \"string\", \"values\": [ \"In\", \"Out\" ] } ],\
-                       \"option\": [ { \"key\": \"PlaceId\", \"type\": \"integer\", \"min\": 1, \"max\": -1 } ]\
-               },\
-               {\
-                       \"name\": \"stats/app/frequency\",\
-                       \"attributes\": [ { \"key\": \"Rank\", \"type\": \"integer\", \"min\": 1, \"max\": -1 }, { \"key\": \"TotalCount\", \"type\": \"integer\", \"min\": 0, \"max\": -1 } ],\
-                       \"option\": [  { \"key\": \"AppId\", \"type\": \"string\", \"values\": [ ] }, { \"key\": \"TimeOfDay\", \"type\": \"string\", \"values\": [ ] }, { \"key\": \"DayOfWeek\", \"type\": \"string\", \"values\": [ \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\", \"Weekday\", \"Weekend\" ] } ]\
-               },\
-               {\
-                       \"name\": \"stats/contact/frequency\",\
-                       \"attributes\": [ { \"key\": \"Rank\", \"type\": \"integer\", \"min\": 1, \"max\": -1 }, { \"key\": \"TotalCount\", \"type\": \"integer\", \"min\": 0, \"max\": -1 } ],\
-                       \"option\": [  { \"key\": \"Address\", \"type\": \"string\", \"values\": [ ] }, { \"key\": \"TimeOfDay\", \"type\": \"string\", \"values\": [ ] }, { \"key\": \"DayOfWeek\", \"type\": \"string\", \"values\": [ \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\", \"Weekday\", \"Weekend\" ] } ]\
-               },\
-               {\
-                       \"name\": \"stats/music/frequency\",\
-                       \"attributes\": [ { \"key\": \"TotalCount\", \"type\": \"integer\", \"min\": 0, \"max\": -1 } ],\
-                       \"option\": [ { \"key\": \"TimeOfDay\", \"type\": \"string\", \"values\": [ ] }, { \"key\": \"DayOfWeek\", \"type\": \"string\", \"values\": [ \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\", \"Weekday\", \"Weekend\" ] } ]\
-               },\
-               {\
-                       \"name\": \"stats/video/frequency\",\
-                       \"attributes\": [ { \"key\": \"TotalCount\", \"type\": \"integer\", \"min\": 0, \"max\": -1 } ],\
-                       \"option\": [ { \"key\": \"TimeOfDay\", \"type\": \"string\", \"values\": [ ] }, { \"key\": \"DayOfWeek\", \"type\": \"string\", \"values\": [ \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\", \"Weekday\", \"Weekend\" ] } ]\
-               }\
-       ]\
-}"
-
-
-namespace ctx {
-}      /* namespace ctx */
-
-#endif /* __CONTEXT_RULE_INFO_H__ */
index 86b20e4..fb1568b 100644 (file)
@@ -20,7 +20,7 @@
 #include <types_internal.h>
 #include <context_trigger.h>
 #include <context_trigger_types_internal.h>
-#include "rule_info.h"
+#include <request_handler.h>
 #include "rule_validator.h"
 
 #define KEY_TEMPLATE "templates"
 #define KEY_MIN "min"
 #define KEY_MAX "max"
 #define KEY_VALUES "values"
-#define NO_LIMIT -1
 #define KEY_REF "ref"
 
 typedef std::map<std::string, ctx::json> template_map_t;
 template_map_t template_map;   // <name, template>
 
-static void init(void);
 static int string_to_int(std::string str);
-static bool check_value_int(ctx::json& tempt, int value);
-static bool check_value_string(ctx::json& tempt, std::string value);
+static bool check_value_int(ctx::json& tmpl, std::string key, int value);
+static bool check_value_string(ctx::json& tmpl, std::string key, std::string value);
+static ctx::json get_template(std::string name);
 
 int string_to_int(std::string str)
 {
@@ -54,37 +53,49 @@ int string_to_int(std::string str)
        return i;
 }
 
-void init(void)
+ctx::json get_template(std::string name)
 {
-       static bool initialized = false;
-       if (initialized)
-               return;
+       ctx::rule_validator::request_template(name);
+       return template_map[name];
+}
+
+int ctx::rule_validator::request_template(std::string name)
+{
+       template_map_t::iterator it = template_map.find(name);
+       IF_FAIL_RETURN(it == template_map.end(), ERR_NONE);
 
-       // Load from Data
-       ctx::json t = ctx::json(static_cast<const char*>(RULE_INFO));
+       // Request template
+       ctx::json request;
+       request.set(NULL, SUBJECT_STR, name);
 
-       ctx::json elem;
-       for (int i = 0; t.get_array_elem(NULL, "templates", i, &elem); i++) {
-               std::string name;
-               elem.get(NULL, "name", &name);
+       int req_id;
+       ctx::json tmpl;
+       int error = ctx::request_handler::read_sync(CONTEXT_TRIGGER_SUBJECT_GET_TEMPLATE, &request, &req_id, &tmpl);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to get request");
 
-               template_map[name] = elem;
-       }
+       template_map[name] = tmpl;
 
-       initialized = true;
+       return ERR_NONE;
 }
 
 // called by context_trigger_rule_add_entry()
 bool ctx::rule_validator::check_option(ctx::json& item)
 {
-       init();
-
        std::string name;
        item.get(NULL, CT_RULE_EVENT_ITEM, &name);
 
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
        // No option needed
-       if (template_map[name].array_get_size(NULL, KEY_OPTION) <= 0)
+       ctx::json opt_tmpl;
+       tmpl.get(NULL, KEY_OPTION, &opt_tmpl);
+
+       std::list<std::string> opt_keys;
+       IF_FAIL_RETURN(opt_tmpl.get_keys(&opt_keys), false);
+       if (opt_keys.size() <= 0) {
                return true;
+       }
 
        // Err: Check if mandatory option is missed
        std::string val_str;
@@ -106,31 +117,25 @@ bool ctx::rule_validator::check_option(ctx::json& item)
 // called by context_trigger_rule_entry_add_option_int()
 bool ctx::rule_validator::check_option_int(std::string name, std::string key, int value)
 {
-       init();
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       ctx::json opt_tmpl;
+       tmpl.get(NULL, KEY_OPTION, &opt_tmpl);
 
        // Err: Item with no option
-       if (template_map[name].array_get_size(NULL, KEY_OPTION) <= 0) {
-               return false;
-       }
+       std::list<std::string> opt_keys;
+       IF_FAIL_RETURN(opt_tmpl.get_keys(&opt_keys), false);
+       IF_FAIL_RETURN(opt_keys.size() > 0, false);
 
        // Err: Invalid option key or Invalid value type
-       bool ret = false;
-       ctx::json opt_tempt;
-       for (int i = 0; template_map[name].get_array_elem(NULL, KEY_OPTION, i, &opt_tempt); i++) {
-               std::string t_key;
-               std::string t_type;
-               opt_tempt.get(NULL, KEY_KEY, &t_key);
-               opt_tempt.get(NULL, KEY_TYPE, &t_type);
-               if (t_key == key && t_type == TYPE_INT_STR) {
-                       ret = true;
-                       break;
-               }
-       }
-       IF_FAIL_RETURN(ret, false);
+       std::string t_type;
+       bool ret = opt_tmpl.get(key.c_str(), KEY_TYPE, &t_type);
+       IF_FAIL_RETURN(ret && t_type == TYPE_INT_STR, false);
 
        // Err: Inappropriate value
        //   a. normal case
-       ret = check_value_int(opt_tempt, value);
+       ret = check_value_int(opt_tmpl, key, value);
        IF_FAIL_RETURN(ret, false);
 
        return true;
@@ -139,30 +144,24 @@ bool ctx::rule_validator::check_option_int(std::string name, std::string key, in
 // called by context_trigger_rule_entry_add_option_string()
 bool ctx::rule_validator::check_option_string(std::string name, std::string key, std::string value)
 {
-       init();
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       ctx::json opt_tmpl;
+       tmpl.get(NULL, KEY_OPTION, &opt_tmpl);
 
        // Err: ';' for SQL injection
        IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
 
        // Err: Item with no option
-       if (template_map[name].array_get_size(NULL, KEY_OPTION) <= 0) {
-               return false;
-       }
+       std::list<std::string> opt_keys;
+       IF_FAIL_RETURN(opt_tmpl.get_keys(&opt_keys), false);
+       IF_FAIL_RETURN(opt_keys.size() > 0, false);
 
        // Err: Invalid option key or Invalid value type
-       bool ret = false;
-       ctx::json opt_tempt;
-       for (int i = 0; template_map[name].get_array_elem(NULL, KEY_OPTION, i, &opt_tempt); i++) {
-               std::string t_key;
-               std::string t_type;
-               opt_tempt.get(NULL, KEY_KEY, &t_key);
-               opt_tempt.get(NULL, KEY_TYPE, &t_type);
-               if (t_key == key && t_type == TYPE_STRING_STR) {
-                       ret = true;
-                       break;
-               }
-       }
-       IF_FAIL_RETURN(ret, false);
+       std::string t_type;
+       bool ret = opt_tmpl.get(key.c_str(), KEY_TYPE, &t_type);
+       IF_FAIL_RETURN(ret && t_type == TYPE_STRING_STR, false);
 
        // Err: Inappropriate value
        //   a. spacial case
@@ -189,7 +188,7 @@ bool ctx::rule_validator::check_option_string(std::string name, std::string key,
        }
 
        //   b. normal case
-       ret = check_value_string(opt_tempt, value);
+       ret = check_value_string(opt_tmpl, key, value);
        IF_FAIL_RETURN(ret, false);
 
        return true;
@@ -198,30 +197,29 @@ bool ctx::rule_validator::check_option_string(std::string name, std::string key,
 // called by context_trigger_rule_entry_add_comparison_int()
 bool ctx::rule_validator::check_comparison_int(std::string name, std::string key, std::string op, int value)
 {
-       init();
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       ctx::json attr_tmpl;
+       tmpl.get(NULL, KEY_ATTR, &attr_tmpl);
 
        // Err: Invalid attribute key or Invalid value type
-       bool ret = false;
-       ctx::json attr_tempt;
-       for (int i = 0; template_map[name].get_array_elem(NULL, KEY_ATTR, i, &attr_tempt); i++) {
-               std::string t_key;
-               std::string t_type;
-               attr_tempt.get(NULL, KEY_KEY, &t_key);
-               attr_tempt.get(NULL, KEY_TYPE, &t_type);
-               if (t_key == key && t_type == TYPE_INT_STR) {
-                       ret = true;
-                       break;
-               }
-       }
-       IF_FAIL_RETURN(ret, false);
+       std::string t_type;
+       bool ret = attr_tmpl.get(key.c_str(), KEY_TYPE, &t_type);
+       IF_FAIL_RETURN(ret && t_type == TYPE_INT_STR, false);
 
        // Err: Invalid operator for the value
+       //    a. normal case
        ret = is_valid_operator(TYPE_INT_STR, op);
        IF_FAIL_RETURN(ret, false);
+       //    b. special case
+       if (name == CT_EVENT_TIME && 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_tempt, value);
+       ret = check_value_int(attr_tmpl, key, value);
        IF_FAIL_RETURN(ret, false);
 
        return true;
@@ -230,25 +228,19 @@ bool ctx::rule_validator::check_comparison_int(std::string name, std::string key
 // called by context_trigger_rule_entry_add_comparison_string()
 bool ctx::rule_validator::check_comparison_string(std::string name, std::string key, std::string op, std::string value)
 {
-       init();
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != ctx::json(EMPTY_JSON_OBJECT), false);
+
+       ctx::json attr_tmpl;
+       tmpl.get(NULL, KEY_ATTR, &attr_tmpl);
 
        // Err: ';' for SQL injection
        IF_FAIL_RETURN(value.find(';') == std::string::npos, false);
 
        // Err: Invalid attribute key or Invalid value type
-       bool ret = false;
-       ctx::json attr_tempt;
-       for (int i = 0; template_map[name].get_array_elem(NULL, KEY_ATTR, i, &attr_tempt); i++) {
-               std::string t_key;
-               std::string t_type;
-               attr_tempt.get(NULL, KEY_KEY, &t_key);
-               attr_tempt.get(NULL, KEY_TYPE, &t_type);
-               if (t_key == key && t_type == TYPE_STRING_STR) {
-                       ret = true;
-                       break;
-               }
-       }
-       IF_FAIL_RETURN(ret, false);
+       std::string t_type;
+       bool ret = attr_tmpl.get(key.c_str(), KEY_TYPE, &t_type);
+       IF_FAIL_RETURN(ret && t_type == TYPE_STRING_STR, false);
 
        // Err: Invalid operator for the value
        ret = is_valid_operator(TYPE_STRING_STR, op);
@@ -256,58 +248,49 @@ bool ctx::rule_validator::check_comparison_string(std::string name, std::string
 
        // Err: Inappropriate value
        //    a. normal case
-       ret = check_value_string(attr_tempt, value);
+       ret = check_value_string(attr_tmpl, key, value);
        IF_FAIL_RETURN(ret, false);
 
        return true;
 }
 
-// called by context_trigger_rule_entry_add_comparison_string()
-bool ctx::rule_validator::check_valid_key(int type, std::string name, std::string key)
+bool ctx::rule_validator::check_valid_key(std::string type, std::string name, std::string key)
 {
-       init();
-       std::string json_key = (type == TYPE_OPTION)? KEY_OPTION : KEY_ATTR;
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
        // Err: Invalid key
-       bool ret = false;
-       ctx::json tempt;
-       for (int i = 0; template_map[name].get_array_elem(NULL, json_key.c_str(), i, &tempt); i++) {
-               std::string t_key;
-               tempt.get(NULL, KEY_KEY, &t_key);
-               if (t_key == key) {
-                       ret = true;
-                       break;
-               }
-       }
+       ctx::json tmp;
+       bool ret = tmpl.get(type.c_str(), key.c_str(), &tmp);
        IF_FAIL_RETURN(ret, false);
 
        return true;
 }
 
-bool check_value_int(ctx::json& tempt, int value)
+bool check_value_int(ctx::json& tmpl, std::string key, int value)
 {
        int min, max;
-       tempt.get(NULL, KEY_MIN, &min);
-       tempt.get(NULL, KEY_MAX, &max);
 
-       if (min != NO_LIMIT && value < min)
-               return false;
+       if (tmpl.get(key.c_str(), KEY_MIN, &min)) {
+               IF_FAIL_RETURN(value >= min, false);
+       }
 
-       if (max != NO_LIMIT && value > max)
-               return false;
+       if (tmpl.get(key.c_str(), KEY_MAX, &max)) {
+               IF_FAIL_RETURN(value <= max, false);
+       }
 
        return true;
 }
 
-bool check_value_string(ctx::json& tempt, std::string value)
+bool check_value_string(ctx::json& tmpl, std::string key, std::string value)
 {
        // case1: any value is accepted
-       if (tempt.array_get_size(NULL, KEY_VALUES) <= 0)
+       if (tmpl.array_get_size(key.c_str(), KEY_VALUES) <= 0)
                return true;
 
        // case2: check acceptable value
        std::string t_val;
-       for (int i = 0; tempt.get_array_elem(NULL, KEY_VALUES, i, &t_val); i++) {
+       for (int i = 0; tmpl.get_array_elem(key.c_str(), KEY_VALUES, i, &t_val); i++) {
                if (t_val == value)
                        return true;
        }
@@ -317,60 +300,49 @@ bool check_value_string(ctx::json& tempt, std::string value)
 
 // called by context_trigger_rule_entry_add_comparison()
 // called by context_trigger_rule_entry_add_option()
-bool ctx::rule_validator::set_ref_info(int type, ctx::json* jref, std::string name, std::string key, std::string ref_data)
+bool ctx::rule_validator::set_ref_info(std::string type, ctx::json* jref, std::string name, std::string key, std::string ref_data)
 {
-       init();
-
-       std::string json_key = (type == TYPE_OPTION)? KEY_OPTION : KEY_ATTR;
-
-       ctx::json tempt;
-       for (int i = 0; template_map[name].get_array_elem(NULL, json_key.c_str(), i, &tempt); i++) {
-               std::string k;
-               std::string dt;
-               tempt.get(NULL, KEY_KEY, &k);
-
-               if (key == k) {
-                       tempt.get(NULL, KEY_TYPE, &dt);
-
-                       ctx::json temp;
-                       temp.set(NULL, KEY_NAME, name);
-                       temp.set(NULL, KEY_KEY, key);
-                       temp.set(NULL, KEY_TYPE, dt);
-                       temp.set(NULL, KEY_REF, ref_data);
-
-                       if (type == TYPE_OPTION) {
-                               jref->array_append(NULL, KEY_OPTION, temp);
-                       } else if (type == TYPE_ATTR) {
-                               jref->array_append(NULL, KEY_ATTR, temp);
-                       } else {
-                               return false;
-                       }
-                       return true;
-               }
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
+
+       ctx::json detailed_tmpl;
+       tmpl.get(NULL, type.c_str(), &detailed_tmpl);
+
+       std::string dt;
+       bool ret = detailed_tmpl.get(key.c_str(), KEY_TYPE, &dt);
+       IF_FAIL_RETURN(ret, false);
+
+       ctx::json temp;
+       temp.set(NULL, KEY_NAME, name);
+       temp.set(NULL, KEY_KEY, key);
+       temp.set(NULL, KEY_TYPE, dt);
+       temp.set(NULL, KEY_REF, ref_data);
+
+       if (type == TYPE_OPTION_STR) {
+               jref->array_append(NULL, KEY_OPTION, temp);
+       } else if (type == TYPE_ATTR_STR) {
+               jref->array_append(NULL, KEY_ATTR, temp);
+       } else {
+               return false;
        }
-       return false;
+
+       return true;;
 }
 
 // called by context_trigger_rule_entry_add_comparison()
-std::string ctx::rule_validator::get_data_type(int type, std::string name, std::string key)
+std::string ctx::rule_validator::get_data_type(std::string type, std::string name, std::string key)
 {
-       init();
+       ctx::json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
-       std::string json_key = (type == TYPE_OPTION)? KEY_OPTION : KEY_ATTR;
+       ctx::json detailed_tmpl;
+       tmpl.get(NULL, type.c_str(), &detailed_tmpl);
 
-       ctx::json tempt;
-       for (int i = 0; template_map[name].get_array_elem(NULL, json_key.c_str(), i, &tempt); i++) {
-               std::string k;
-               tempt.get(NULL, KEY_KEY, &k);
-
-               if (key == k) {
-                       std::string dt;
-                       tempt.get(NULL, KEY_TYPE, &dt);
-                       return dt;
-               }
-       }
+       std::string dt;
+       bool ret = detailed_tmpl.get(key.c_str(), KEY_TYPE, &dt);
+       IF_FAIL_RETURN(ret, "");
 
-       return "";
+       return dt;
 }
 
 // called by context_trigger_rule_add_entry()
@@ -386,7 +358,7 @@ bool ctx::rule_validator::check_referential_data(std::string name, ctx::json& re
                ref_data.get(NULL, KEY_TYPE, &cond_type);
 
                if (type_map.count(ref_key) == 0) {
-                       type_map[ref_key] = get_data_type(TYPE_ATTR, name, ref_key); // -1, if invalid key
+                       type_map[ref_key] = get_data_type(TYPE_ATTR_STR, name, ref_key); // "", if invalid key
                }
 
                // Err: Invalid key or Value type not matched
@@ -401,7 +373,7 @@ bool ctx::rule_validator::check_referential_data(std::string name, ctx::json& re
                ref_data.get(NULL, KEY_TYPE, &cond_type);
 
                if (type_map.count(ref_key) == 0) {
-                       type_map[ref_key] = get_data_type(TYPE_ATTR, name, ref_key); // -1, if invalid key
+                       type_map[ref_key] = get_data_type(TYPE_ATTR_STR, name, ref_key); // "", if invalid key
                }
 
                // Err: Invalid key or Value type not matched
index 1ca63d5..72c8e6a 100644 (file)
 namespace ctx {
        namespace rule_validator {
 
+               int request_template(std::string name);
                bool check_option(ctx::json &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::json &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(int type, std::string name, std::string key);
+               bool check_valid_key(std::string type, std::string name, std::string key);
 
-               bool set_ref_info(int type, ctx::json *jref, std::string name, std::string key, std::string ref_key);
-               std::string get_data_type(int type, std::string name, std::string key);
+               bool set_ref_info(std::string type, ctx::json *jref, std::string name, std::string key, std::string ref_key);
+               std::string get_data_type(std::string type, std::string name, std::string key);
                bool check_referential_data(std::string name, ctx::json &ref_info);
                bool is_valid_operator(std::string type, std::string op);