Added trigger rule class. 88/56588/1
authorSomin Kim <somin926.kim@samsung.com>
Mon, 11 Jan 2016 09:31:25 +0000 (18:31 +0900)
committerSomin Kim <somin926.kim@samsung.com>
Mon, 11 Jan 2016 09:31:25 +0000 (18:31 +0900)
- Removed script generator, clips handler.
- Timer event/condition not working
- Condition not working

Change-Id: I7e22e692825f7ddf25539d583d10389428cc2471
Signed-off-by: Somin Kim <somin926.kim@samsung.com>
19 files changed:
src/context_mgr_impl.h
src/context_trigger/action_manager.cpp [new file with mode: 0644]
src/context_trigger/action_manager.h [new file with mode: 0644]
src/context_trigger/clips_handler.cpp [deleted file]
src/context_trigger/clips_handler.h [deleted file]
src/context_trigger/context_listener_iface.h [new file with mode: 0644]
src/context_trigger/context_monitor.cpp
src/context_trigger/context_monitor.h
src/context_trigger/rule.cpp [new file with mode: 0644]
src/context_trigger/rule.h [new file with mode: 0644]
src/context_trigger/rule_evaluator.cpp [new file with mode: 0644]
src/context_trigger/rule_evaluator.h [new file with mode: 0644]
src/context_trigger/rule_manager.cpp
src/context_trigger/rule_manager.h
src/context_trigger/script_generator.cpp [deleted file]
src/context_trigger/script_generator.h [deleted file]
src/context_trigger/timer.cpp
src/context_trigger/trigger.cpp
src/context_trigger/trigger.h

index f8847610e1cf2778aa3ddbf72cee889057dffcd0..52815953966c17826d074c09bb7f9b930a0fdb7f 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <string>
 #include <map>
+#include <glib.h>
 #include <context_mgr.h>
 #include <context_mgr_iface.h>
 
diff --git a/src/context_trigger/action_manager.cpp b/src/context_trigger/action_manager.cpp
new file mode 100644 (file)
index 0000000..ccf7b4e
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * 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 <app_control.h>
+#include <app_control_internal.h>
+#include <appsvc.h>
+#include <bundle.h>
+#include <device/display.h>
+#include <glib.h>
+#include <notification.h>
+#include <notification_internal.h>
+#include <runtime_info.h>
+#include <system_settings.h>
+#include <stdlib.h>
+#include <context_trigger_types_internal.h>
+#include "../dbus_server_impl.h"
+//#include <string>
+//#include <json.h>
+//#include <types_internal.h>
+#include "action_manager.h"
+
+static void trigger_action_app_control(ctx::json& action);
+static void trigger_action_notification(ctx::json& action, std::string app_id);        // TODO appid? creator?
+static void trigger_action_dbus_call(ctx::json& action);
+
+void ctx::action_manager::trigger_action(ctx::json& action, std::string creator)
+{
+       std::string type;
+       action.get(NULL, CT_RULE_ACTION_TYPE, &type);
+
+       if (type.compare(CT_RULE_ACTION_TYPE_APP_CONTROL) == 0) {
+               trigger_action_app_control(action);
+       } else if (type.compare(CT_RULE_ACTION_TYPE_NOTIFICATION) == 0) {
+               trigger_action_notification(action, creator);
+       } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) {
+               trigger_action_dbus_call(action);
+       }
+}
+
+void trigger_action_app_control(ctx::json& action)
+{
+       int error;
+       std::string appctl_str;
+       action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str);
+
+       char* str = static_cast<char*>(malloc(appctl_str.length()));
+       if (str == NULL) {
+               _E("Memory allocation failed");
+               return;
+       }
+       appctl_str.copy(str, appctl_str.length(), 0);
+       bundle_raw* encoded = reinterpret_cast<unsigned char*>(str);
+       bundle* appctl_bundle = bundle_decode(encoded, appctl_str.length());
+
+       app_control_h app = NULL;
+       app_control_create(&app);
+       app_control_import_from_bundle(app, appctl_bundle);
+
+       error = app_control_send_launch_request(app, NULL, NULL);
+       if (error != APP_CONTROL_ERROR_NONE) {
+               _E("Launch request failed(%d)", error);
+       } else {
+               _D("Launch request succeeded");
+       }
+       bundle_free(appctl_bundle);
+       free(str);
+       app_control_destroy(app);
+
+       error = device_display_change_state(DISPLAY_STATE_NORMAL);
+       if (error != DEVICE_ERROR_NONE) {
+               _E("Change display state failed(%d)", error);
+       }
+}
+
+void trigger_action_notification(ctx::json& action, std::string app_id)        // TODO appid? creator?
+{
+       int error;
+       notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI);
+       std::string title;
+       if (action.get(NULL, CT_RULE_ACTION_NOTI_TITLE, &title)) {
+               error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_TITLE, title.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+               if (error != NOTIFICATION_ERROR_NONE) {
+                       _E("Set notification title failed(%d)", error);
+               }
+       }
+
+       std::string content;
+       if (action.get(NULL, CT_RULE_ACTION_NOTI_CONTENT, &content)) {
+               error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_CONTENT, content.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+               if (error != NOTIFICATION_ERROR_NONE) {
+                       _E("Set notification contents failed(%d)", error);
+               }
+       }
+
+       std::string image_path;
+       if (action.get(NULL, CT_RULE_ACTION_NOTI_ICON_PATH, &image_path)) {
+               error = notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, image_path.c_str());
+               if (error != NOTIFICATION_ERROR_NONE) {
+                       _E("Set notification icon image failed(%d)", error);
+               }
+       }
+
+       std::string appctl_str;
+       char* str = NULL;
+       bundle_raw* encoded = NULL;
+       bundle* appctl_bundle = NULL;
+       app_control_h app = NULL;
+       if (action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str)) {
+               str = static_cast<char*>(malloc(appctl_str.length()));
+               if (str == NULL) {
+                       _E("Memory allocation failed");
+                       notification_free(notification);
+                       return;
+               }
+               appctl_str.copy(str, appctl_str.length(), 0);
+               encoded = reinterpret_cast<unsigned char*>(str);
+               appctl_bundle = bundle_decode(encoded, appctl_str.length());
+
+               app_control_create(&app);
+               app_control_import_from_bundle(app, appctl_bundle);
+
+               error = notification_set_launch_option(notification, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, app);
+               if (error != NOTIFICATION_ERROR_NONE) {
+                       _E("Set launch option failed(%d)", error);
+               }
+       }
+
+       if (!app_id.empty()) {
+               error = notification_set_pkgname(notification, app_id.c_str());
+               if (error != NOTIFICATION_ERROR_NONE) {
+                       _E("Set pkgname(%s) failed(%d)", app_id.c_str(), error);
+               }
+       }
+
+       bool silent = true;
+       error = system_settings_get_value_bool(SYSTEM_SETTINGS_KEY_SOUND_SILENT_MODE, &silent);
+       if (error != SYSTEM_SETTINGS_ERROR_NONE) {
+               _E("Get system setting(silent mode) failed(%d)", error);
+       }
+
+       bool vibration = true;
+       error = runtime_info_get_value_bool(RUNTIME_INFO_KEY_VIBRATION_ENABLED, &vibration);
+       if (error != RUNTIME_INFO_ERROR_NONE) {
+               _E("Get runtime info(vibration) failed(%d)", error);
+       }
+
+       if (!silent) {
+           error = notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL);
+               if (error != NOTIFICATION_ERROR_NONE) {
+                       _E("Set notification sound failed(%d)", error);
+               }
+
+               if (vibration) {
+                       error = notification_set_vibration(notification, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL);
+                       if (error != NOTIFICATION_ERROR_NONE) {
+                               _E("Set notification vibration failed(%d)", error);
+                       }
+               }
+       }
+
+       error = notification_post(notification);
+       if (error != NOTIFICATION_ERROR_NONE) {
+               _E("Post notification failed(%d)", error);
+       } else {
+               _D("Post notification succeeded");
+       }
+
+       bundle_free(appctl_bundle);
+       free(str);
+       notification_free(notification);
+       if (app) {
+               app_control_destroy(app);
+       }
+
+       error = device_display_change_state(DISPLAY_STATE_NORMAL);
+       if (error != DEVICE_ERROR_NONE) {
+               _E("Change display state failed(%d)", error);
+       }
+}
+
+void trigger_action_dbus_call(ctx::json& action)
+{
+       std::string bus_name, object, iface, method;
+       GVariant *param = NULL;
+
+       action.get(NULL, CT_RULE_ACTION_DBUS_NAME, &bus_name);
+       IF_FAIL_VOID_TAG(!bus_name.empty(), _E, "No target bus name");
+
+       action.get(NULL, CT_RULE_ACTION_DBUS_OBJECT, &object);
+       IF_FAIL_VOID_TAG(!object.empty(), _E, "No object path");
+
+       action.get(NULL, CT_RULE_ACTION_DBUS_INTERFACE, &iface);
+       IF_FAIL_VOID_TAG(!iface.empty(), _E, "No interface name");
+
+       action.get(NULL, CT_RULE_ACTION_DBUS_METHOD, &method);
+       IF_FAIL_VOID_TAG(!method.empty(), _E, "No method name");
+
+       action.get(NULL, CT_RULE_ACTION_DBUS_PARAMETER, &param);
+
+       ctx::dbus_server::call(bus_name.c_str(), object.c_str(), iface.c_str(), method.c_str(), param);
+}
diff --git a/src/context_trigger/action_manager.h b/src/context_trigger/action_manager.h
new file mode 100644 (file)
index 0000000..0bce8ea
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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_ACTION_MANAGER_H__
+#define __CONTEXT_ACTION_MANAGER_H__
+
+#include <json.h>
+
+namespace ctx {
+
+       class json;
+
+       namespace action_manager {
+
+               void trigger_action(ctx::json& action, std::string creator);
+
+       }
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_ACTION_MANAGER_H__ */
diff --git a/src/context_trigger/clips_handler.cpp b/src/context_trigger/clips_handler.cpp
deleted file mode 100644 (file)
index 2f2b749..0000000
+++ /dev/null
@@ -1,263 +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 <types_internal.h>
-#include <json.h>
-#include <string>
-#include <sstream>
-#include <cstdlib>
-#include "clips_handler.h"
-#include "rule_manager.h"
-
-extern "C"
-{
-#include <clips/clips.h>
-}
-
-static void* env = NULL;
-static ctx::rule_manager* rule_mgr = NULL;
-static int string_to_int(std::string str);
-
-ctx::clips_handler::clips_handler(ctx::rule_manager* rm)
-{
-       rule_mgr = rm;
-       init_environment();
-       _D(YELLOW("Clips handler initialized"));
-}
-
-ctx::clips_handler::~clips_handler()
-{
-       if (env) {
-               DestroyEnvironment(env);
-               env = NULL;
-       }
-
-       _D(YELLOW("Clips handler destroyed"));
-}
-
-int ctx::clips_handler::init_environment(void)
-{
-       if (env) {
-               _D("Clips environment already created");
-               return ERR_NONE;
-       }
-
-       env = CreateEnvironment();
-       if (!env) {
-               _E("Create environment failed");
-               return ERR_OPERATION_FAILED;
-       }
-
-       char* func_name = strdup("execute_action");
-       char* restrictions = strdup("1s");
-
-       if (func_name == NULL || restrictions == NULL) {
-               _E("Memory allocation failed");
-               free(func_name);
-               free(restrictions);
-               return ERR_OUT_OF_MEMORY;
-       }
-
-       EnvDefineFunction2(env, func_name, 'i', PTIEF execute_action, func_name, restrictions);
-       free(func_name);
-       free(restrictions);
-
-       return ERR_NONE;
-}
-
-int ctx::clips_handler::define_template(std::string& script)
-{
-       IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Deftemplate failed");
-       return ERR_NONE;
-}
-
-int ctx::clips_handler::define_class(std::string& script)
-{
-       IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Defclass failed");
-       return ERR_NONE;
-}
-
-int ctx::clips_handler::define_rule(std::string& script)
-{
-       IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Defrule failed");
-       return ERR_NONE;
-}
-
-int ctx::clips_handler::env_build(std::string& script)
-{
-       ASSERT_NOT_NULL(env);
-       if (script.length() == 0)
-               return ERR_INVALID_PARAMETER;
-
-       _I("EnvBuild script (%s)", script.c_str());
-       int ret = EnvBuild(env, script.c_str());
-
-       return (ret == 1)? ERR_NONE : ERR_OPERATION_FAILED;
-}
-
-int ctx::clips_handler::run_environment()
-{
-       ASSERT_NOT_NULL(env);
-
-       int fired_rule_num = EnvRun(env, -1);
-       IF_FAIL_RETURN(fired_rule_num >= 0, ERR_OPERATION_FAILED);
-
-       return ERR_NONE;
-}
-
-int ctx::clips_handler::add_fact(std::string& fact)
-{
-       ASSERT_NOT_NULL(env);
-       if (fact.length() == 0)
-               return ERR_INVALID_PARAMETER;
-
-       void* assert_fact = EnvAssertString(env, fact.c_str());
-       IF_FAIL_RETURN_TAG(assert_fact, ERR_OPERATION_FAILED, _E, "Fact assertion failed");
-
-       return ERR_NONE;
-}
-
-int ctx::clips_handler::route_string_command(std::string& script)
-{
-       ASSERT_NOT_NULL(env);
-       if (script.length() == 0)
-               return ERR_INVALID_PARAMETER;
-
-       int error;
-       if (RouteCommand(env, script.c_str(), TRUE)){
-               _D("Route command succeeded(%s).", script.c_str());
-               error = ERR_NONE;
-       } else {
-               _E("Route command failed");
-               error = ERR_OPERATION_FAILED;
-       }
-
-       return error;
-}
-
-int ctx::clips_handler::make_instance(std::string& script)
-{
-       ASSERT_NOT_NULL(env);
-       if (script.length() == 0)
-               return ERR_INVALID_PARAMETER;
-
-       int error;
-       if (EnvMakeInstance(env, script.c_str())){
-               _D("Make instance succeeded - %s", script.c_str());
-               error = ERR_NONE;
-       } else {
-               _E("Make instance failed");
-               error = ERR_OPERATION_FAILED;
-       }
-
-       return error;
-}
-
-int ctx::clips_handler::unmake_instance(std::string& instance_name)
-{
-       ASSERT_NOT_NULL(env);
-       if (instance_name.length() == 0)
-               return ERR_INVALID_PARAMETER;
-
-       void* instance = find_instance_internal(instance_name);
-       if (!instance) {
-               _E("Cannot find instance(%s).", instance_name.c_str());
-               return ERR_INVALID_PARAMETER;
-       }
-
-       if (!EnvUnmakeInstance(env, instance)){
-               _E("Unmake instance failed");
-               return ERR_OPERATION_FAILED;
-       }
-
-       _D("Unmake instance succeeded(%s).", instance_name.c_str());
-       return ERR_NONE;
-}
-
-int ctx::clips_handler::execute_action(void)
-{
-       ASSERT_NOT_NULL(env);
-
-       const char* result = EnvRtnLexeme(env, 1);
-       if (!result) {
-               _E("Failed to get returned rule id");
-               return ERR_OPERATION_FAILED;
-       }
-       std::string rule_id = result;
-       std::string id_str = rule_id.substr(4);
-
-       int id = string_to_int(id_str);
-       rule_mgr->on_rule_triggered(id);
-
-       return ERR_NONE;
-}
-
-bool ctx::clips_handler::find_instance(std::string& instance_name)
-{
-       ASSERT_NOT_NULL(env);
-
-       if (find_instance_internal(instance_name)) {
-               _D("[%s] already exists", instance_name.c_str());
-               return true;
-       }
-
-       return false;
-}
-
-void* ctx::clips_handler::find_instance_internal(std::string& instance_name)
-{
-       void* instance = EnvFindInstance(env, NULL, instance_name.c_str(), TRUE);
-       return instance;
-}
-
-int string_to_int(std::string str)
-{
-       int i;
-       std::istringstream convert(str);
-
-       if (!(convert >> i))
-               i = 0;
-
-       return i;
-}
-
-bool ctx::clips_handler::define_global_variable_string(std::string variable_name, std::string value)
-{
-       std::string script = "(defglobal ?*";
-       script += variable_name;
-       script += "* = \"";
-       script += value;
-       script += "\")";
-
-       IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, false, _E, "Defglobal failed");
-       return true;
-}
-
-bool ctx::clips_handler::set_global_variable_string(std::string variable_name, std::string value)
-{
-       ASSERT_NOT_NULL(env);
-       if (variable_name.length() == 0)
-               return false;
-
-       DATA_OBJECT data;
-       SetType(data, STRING);
-       SetValue(data, EnvAddSymbol(env, value.c_str())) ;
-
-       int ret = EnvSetDefglobalValue(env, variable_name.c_str(), &data);
-
-       IF_FAIL_RETURN_TAG(ret == 1, false, _E, "Set global variable(%s) failed", variable_name.c_str());
-       return true;
-}
diff --git a/src/context_trigger/clips_handler.h b/src/context_trigger/clips_handler.h
deleted file mode 100644 (file)
index 0ebb747..0000000
+++ /dev/null
@@ -1,53 +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 __CLIPS_HANDLER_H__
-#define __CLIPS_HANDLER_H__
-
-namespace ctx {
-
-       class json;
-       class rule_manager;
-
-       class clips_handler {
-               public:
-                       clips_handler(ctx::rule_manager* rm);
-                       ~clips_handler();
-
-                       int define_template(std::string& script);
-                       int define_class(std::string& script);
-                       int define_rule(std::string& script);
-                       int run_environment();
-                       int add_fact(std::string& fact);
-                       int route_string_command(std::string& fact);
-                       int make_instance(std::string& script);
-                       int unmake_instance(std::string& instance_name);
-                       static int execute_action(void);
-                       bool find_instance(std::string& instance_name);
-                       bool define_global_variable_string(std::string variable_name, std::string value);
-                       bool set_global_variable_string(std::string variable_name, std::string value);
-
-               private:
-                       clips_handler();
-                       int init_environment(void);
-                       int env_build(std::string& script);
-                       void* find_instance_internal(std::string& instance_name);
-
-   };  /* class clips_handler */
-
-}      /* namespace ctx */
-
-#endif /* End of __CLIPS_HANDLER_H__ */
diff --git a/src/context_trigger/context_listener_iface.h b/src/context_trigger/context_listener_iface.h
new file mode 100644 (file)
index 0000000..657f07f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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_CONTEXT_LISTENER_INTERFACE_H__
+#define __CONTEXT_CONTEXT_LISTENER_INTERFACE_H__
+
+namespace ctx {
+       /* Forward Declaration */
+       class json;
+
+       class context_listener_iface {
+               public:
+                       virtual ~context_listener_iface() {}
+
+                       virtual void on_event_received(std::string name, ctx::json option, ctx::json data) = 0;
+
+                       virtual void on_condition_received(std::string name, ctx::json option, ctx::json data) = 0;
+       };
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_CONTEXT_LISTENER_INTERFACE_H__ */
index 98c51677d39ecf6b031e0f7c40f62ac3a06945cf..b86d3dc805b785345dd9bbdfb3d97b66d0bd495b 100644 (file)
  */
 
 #include <types_internal.h>
-#include <json.h>
-#include <context_trigger_types_internal.h>
-#include "trigger.h"
 #include "../access_control/privilege.h"
+#include "../context_mgr_impl.h"
 #include "context_monitor.h"
 #include "fact_request.h"
+#include "timer.h"
 #include "timer_types.h"
+#include "context_listener_iface.h"
 
 static int last_rid;
 static int last_err;
@@ -50,41 +50,38 @@ ctx::context_monitor::~context_monitor()
        delete timer;
 }
 
-bool ctx::context_monitor::init(ctx::context_manager_impl* ctx_mgr, ctx::context_trigger* tr)
+bool ctx::context_monitor::init(ctx::context_manager_impl* ctx_mgr)
 {
        _context_mgr = ctx_mgr;
-       _trigger = tr;
 
-       timer = new(std::nothrow) trigger_timer(_trigger);
-       IF_FAIL_RETURN_TAG(timer, false, _E, "Memory allocation failed");
+/*     timer = new(std::nothrow) trigger_timer(_trigger);      TODO
+       IF_FAIL_RETURN_TAG(timer, false, _E, "Memory allocation failed");*/
 
        return true;
 }
 
-int ctx::context_monitor::subscribe(int rule_id, std::string subject, ctx::json event)
+int ctx::context_monitor::subscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener)
 {
        if (subject.compare(TIMER_EVENT_SUBJECT) == 0) {
                // option is event json in case of ON_TIME
-               return timer->subscribe(event);
+//             return timer->subscribe(event);
+               return ERR_NONE;
        }
 
-       ctx::json eoption = NULL;
-       event.get(NULL, CT_RULE_EVENT_OPTION, &eoption);
-
-       int req_id = _subscribe(subject.c_str(), &eoption, true);
+       int req_id = _subscribe(subject.c_str(), &option, listener, true);
        IF_FAIL_RETURN_TAG(req_id > 0, ERR_OPERATION_FAILED, _E, "Subscribe event failed");
        _D(YELLOW("Subscribe event(rule%d). req%d"), rule_id, req_id);
 
        return ERR_NONE;
 }
 
-int ctx::context_monitor::_subscribe(const char* subject, json* option, bool wait_response)
+int ctx::context_monitor::_subscribe(const char* subject, json* option, context_listener_iface* listener, bool wait_response)
 {
        IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
 
        int rid = find_sub(subject, option);
        if (rid > 0) {
-               increase_sub(rid);
+               add_listener(rid, listener);
                _D("Duplicated request for %s", subject);
                return rid;
        }
@@ -96,7 +93,7 @@ int ctx::context_monitor::_subscribe(const char* subject, json* option, bool wai
        IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed");
 
        send_request(req);      //TODO: what happens if the request actually takes more time than the timeout
-       add_sub(rid, subject, option);
+       add_sub(rid, subject, option, listener);
 
        IF_FAIL_RETURN_TAG(wait_response, rid, _D, "Ignoring response for %s", subject);
 
@@ -109,22 +106,20 @@ int ctx::context_monitor::_subscribe(const char* subject, json* option, bool wai
        return rid;
 }
 
-int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::json option)
+int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener)
 {
        if (subject.compare(TIMER_EVENT_SUBJECT) == 0) {
-               return timer->unsubscribe(option);
+//             return timer->unsubscribe(option);
+               return ERR_NONE;
        }
 
-       ctx::json eoption = NULL;
-       option.get(NULL, CT_RULE_EVENT_OPTION, &eoption);
-
-       int rid = find_sub(subject.c_str(), &eoption);
+       int rid = find_sub(subject.c_str(), &option);
        if (rid < 0) {
                _D("Invalid unsubscribe request");
                return ERR_INVALID_PARAMETER;
        }
 
-       if (decrease_sub(rid) <= 0) {
+       if (remove_listener(rid, listener) <= 0) {
                _unsubscribe(subject.c_str(), rid);
        }
        _D(YELLOW("Unsubscribe event(rule%d). req%d"), rule_id, rid);
@@ -149,22 +144,23 @@ bool ctx::context_monitor::send_request(fact_request* req)
 
 int ctx::context_monitor::read(std::string subject, json option, ctx::json* result)
 {
-       bool ret;
        if (subject.compare(TIMER_CONDITION_SUBJECT) == 0) {
-               return timer->read(result);
+//             return timer->read(result);     TODO
+               return ERR_NONE;
        }
 
-       context_fact fact;
-       ret = _read(subject.c_str(), &option, fact);
+/*     context_fact fact;
+       bool ret = _read(subject.c_str(), &option, fact);
        IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Read fact failed");
 
        *result = fact.get_data();
-
+*/
        return ERR_NONE;
 }
 
-bool ctx::context_monitor::_read(const char* subject, json* option, context_fact& fact)
+/*bool ctx::context_monitor::_read(const char* subject, json* option, context_fact& fact)
 {
+       // TODO implement read async
        IF_FAIL_RETURN(subject, false);
 
        int rid = generate_req_id();
@@ -187,7 +183,7 @@ bool ctx::context_monitor::_read(const char* subject, json* option, context_fact
 
        return true;
 }
-
+*/
 bool ctx::context_monitor::is_supported(std::string subject)
 {
        if (subject.compare(TIMER_EVENT_SUBJECT) == 0
@@ -202,8 +198,8 @@ bool ctx::context_monitor::is_allowed(const char *client, const char *subject)
 {
        if (STR_EQ(subject, TIMER_EVENT_SUBJECT))
                return true;
-       //TODO: re-implement above in the proper 3.0 style
-       //      return privilege_manager::is_allowed(client, PRIV_ALARM_SET);
+               //TODO: re-implement above in the proper 3.0 style
+               //              return privilege_manager::is_allowed(client, PRIV_ALARM_SET);
 
        if (STR_EQ(subject, TIMER_CONDITION_SUBJECT))
                return true;
@@ -220,6 +216,7 @@ bool ctx::context_monitor::get_fact_definition(std::string &subject, int &operat
 
 int ctx::context_monitor::find_sub(const char* subject, json* option)
 {
+       // @return      request id
        json opt_j;
        if (option) {
                opt_j = *option;
@@ -234,13 +231,13 @@ int ctx::context_monitor::find_sub(const char* subject, json* option)
        return -1;
 }
 
-bool ctx::context_monitor::add_sub(int sid, const char* subject, json* option)
+bool ctx::context_monitor::add_sub(int sid, const char* subject, json* option, context_listener_iface* listener)
 {
        subscr_info_s *info = new(std::nothrow) subscr_info_s(sid, subject, option);
        IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
+       info->listener_list.push_back(listener);
 
        subscr_map[sid] = info;
-
        return true;
 }
 
@@ -262,29 +259,41 @@ void ctx::context_monitor::remove_sub(const char* subject, json* option)
 
 void ctx::context_monitor::remove_sub(int sid)
 {
+       subscr_info_s* info = subscr_map[sid];
+       info->listener_list.clear();
+
+       delete info;
        subscr_map.erase(sid);
 
        return;
 }
 
-int ctx::context_monitor::increase_sub(int sid)
+int ctx::context_monitor::add_listener(int sid, context_listener_iface* listener)
 {
+       // @return      number of listeners for the corresponding sid
        subscr_map_t::iterator it = subscr_map.find(sid);
 
        subscr_info_s* info = it->second;
-       info->cnt++;
+       info->listener_list.push_back(listener);
 
-       return info->cnt;
+       return info->listener_list.size();
 }
 
-int ctx::context_monitor::decrease_sub(int sid)
+int ctx::context_monitor::remove_listener(int sid, context_listener_iface* listener)
 {
+       // @return      number of listeners for the corresponding sid
        subscr_map_t::iterator it = subscr_map.find(sid);
 
        subscr_info_s* info = it->second;
-       info->cnt--;
 
-       return info->cnt;
+       for (listener_list_t::iterator it2 = info->listener_list.begin(); it2 != info->listener_list.end(); ++it2) {
+               if (*it2 == listener) {
+                       info->listener_list.erase(it2);
+                       break;
+               }
+       }
+
+       return info->listener_list.size();
 }
 
 void ctx::context_monitor::reply_result(int req_id, int error, json* request_result, json* fact)
@@ -299,8 +308,12 @@ void ctx::context_monitor::publish_fact(int req_id, int error, const char* subje
 {
        _D(YELLOW("Fact received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
 
-       // TODO: deliver fact to each rule instance
+       subscr_map_t::iterator it = subscr_map.find(req_id);
+       IF_FAIL_VOID_TAG(it != subscr_map.end(), _E, "Request id not found");
+
+       subscr_info_s* info = it->second;
+       for (listener_list_t::iterator it2 = info->listener_list.begin(); it2 != info->listener_list.end(); ++it2) {
+               (*it2)->on_event_received(subject, *option, *fact);
+       }
 
-       // TODO Remove
-       _trigger->push_fact(req_id, error, subject, *option, *fact);
 }
index 3fc6f0171d20545830b57d8e5822f6260bf6dcf5..f53157eb04a66c88860550b4e92d5ecaeb13e1d9 100644 (file)
 #include <list>
 #include <map>
 #include <json.h>
-#include "../context_mgr_impl.h"
-#include "fact.h"
-#include "timer.h"
 
 namespace ctx {
 
-       class json;
-       class context_fact;
        class fact_request;
+       class context_manager_impl;
+       class context_listener_iface;
+       class trigger_timer;
 
        class context_monitor {
        public:
                context_monitor();
                ~context_monitor();
-               bool init(ctx::context_manager_impl* ctx_mgr, ctx::context_trigger* tr);
+               bool init(ctx::context_manager_impl* ctx_mgr);
 
-               int subscribe(int rule_id, std::string subject, ctx::json event);
-               int unsubscribe(int rule_id, std::string subject, ctx::json option);
+               int subscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener);
+               int unsubscribe(int rule_id, std::string subject, ctx::json option, context_listener_iface* listener);
                int read(std::string subject, json option, ctx::json* result);
                bool is_supported(std::string subject);
                bool is_allowed(const char *client, const char *subject);
 
-               void reply_result(int req_id, int error, json *request_result = NULL, json *fact = NULL);
-               void publish_fact(int req_id, int error, const char *subject, json *option, json *fact);
+               void reply_result(int req_id, int error, json *request_result = NULL, ctx::json *fact = NULL);
+               void publish_fact(int req_id, int error, const char *subject, json *option, ctx::json *fact);
 
                bool get_fact_definition(std::string &subject, int &operation, ctx::json &attributes, ctx::json &options);
 
        private:
-               int _subscribe(const char* subject, json* option, bool wait_response);
+               int _subscribe(const char* subject, ctx::json* option, context_listener_iface* listener, bool wait_response);
                void _unsubscribe(const char *subject, int subscription_id);
-               bool _read(const char *subject, json *option, context_fact& fact);
+//             bool _read(const char *subject, ctx::json *option, context_fact& fact);
 
-               ctx::context_trigger* _trigger;
                ctx::trigger_timer* timer;
                static context_manager_impl *_context_mgr;
 
+               typedef std::list<context_listener_iface*> listener_list_t;
+
                struct subscr_info_s {
                        int sid;
-                       int cnt;
                        std::string subject;
                        ctx::json option;
+                       listener_list_t listener_list;
+
                        subscr_info_s(int id, const char *subj, ctx::json *opt)
-                               : sid(id), cnt(1), subject(subj)
+                               : sid(id), subject(subj)
                        {
                                if (opt)
                                        option = *opt;
@@ -72,12 +72,12 @@ namespace ctx {
                typedef std::map<int, subscr_info_s*> subscr_map_t;
                subscr_map_t subscr_map;
 
-               int find_sub(const char *subject, json *option);
-               bool add_sub(int sid, const char *subject, json *option);
-               void remove_sub(const char *subject, json *option);
+               int find_sub(const char *subject, ctx::json *option);
+               bool add_sub(int sid, const char *subject, ctx::json *option, context_listener_iface* listener);
+               void remove_sub(const char *subject, ctx::json *option);
                void remove_sub(int sid);
-               int increase_sub(int sid);
-               int decrease_sub(int sid);
+               int add_listener(int sid, context_listener_iface* listener);
+               int remove_listener(int sid, context_listener_iface* listener);
 
                static bool send_request(fact_request* req);
        };      /* class context_monitor */
diff --git a/src/context_trigger/rule.cpp b/src/context_trigger/rule.cpp
new file mode 100644 (file)
index 0000000..7d15056
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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 <context_trigger_types_internal.h>
+#include "rule.h"
+#include "action_manager.h"
+#include "rule_evaluator.h"
+#include "context_monitor.h"
+
+#define CONTEXT_RULE_EVENT "event"
+#define CONTEXT_RULE_CONDITION "condition"
+#define CONTEXT_RULE_NAME "name"
+#define CONTEXT_RULE_OPTION "option"
+#define CONTEXT_RULE_DATA "data"
+
+ctx::trigger_rule::trigger_rule()
+{
+}
+
+ctx::trigger_rule::trigger_rule(int i, ctx::json& d, const char* cr, context_monitor* cm)
+       : ctx_monitor(cm)
+       , id(i)
+       , creator(cr)
+{
+       // Statement
+       statement = d.str();
+
+       // Event
+       ctx::json e;
+       d.get(NULL, CT_RULE_EVENT, &e);
+       event = new(std::nothrow) context_item_s(e);
+
+       // Condition
+       int cond_num = d.array_get_size(NULL, CT_RULE_CONDITION);
+       for (int j = 0; j < cond_num; j++) {
+               ctx::json c;
+               d.get_array_elem(NULL, CT_RULE_CONDITION, j, &c);
+               condition.push_back(new(std::nothrow) context_item_s(c));
+       }
+
+       // Action
+       ctx::json a;
+       d.get(NULL, CT_RULE_ACTION, &a);
+       action = a.str();
+}
+
+ctx::trigger_rule::~trigger_rule()
+{
+       // Release resources
+       delete event;
+       for (std::list<context_item_t>::iterator it = condition.begin(); it != condition.end(); ++it) {
+               delete *it;
+       }
+}
+
+int ctx::trigger_rule::start(void)
+{
+       // Subscribe event
+       int error = ctx_monitor->subscribe(id, event->name, event->option, this);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to start rule%d", id);
+
+       return error;
+}
+
+int ctx::trigger_rule::stop(void)
+{
+       // Unsubscribe event
+       int error = ctx_monitor->unsubscribe(id, event->name, event->option, this);
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id);
+
+       return error;
+}
+
+void ctx::trigger_rule::on_event_received(std::string name, ctx::json option, ctx::json data)
+{
+       clear_result();
+       _D("Rule%d received event data", id);
+
+       // Set event data
+       result.set(CONTEXT_RULE_EVENT, CONTEXT_RULE_NAME, name);
+       result.set(CONTEXT_RULE_EVENT, CONTEXT_RULE_OPTION, option);
+       result.set(CONTEXT_RULE_EVENT, CONTEXT_RULE_DATA, data);
+
+       if (condition.size() == 0) {
+               on_context_data_prepared(data);
+               return;
+       }
+
+       for (std::list<context_item_t>::iterator it = condition.begin(); it != condition.end(); ++it) {
+               // TODO send read request for each condition
+       }
+
+       // TODO timer set
+}
+
+void ctx::trigger_rule::on_condition_received(std::string name, ctx::json option, ctx::json data)
+{
+       // Set condition data
+       ctx::json item;
+       item.set(NULL, CONTEXT_RULE_NAME, name);
+       item.set(NULL, CONTEXT_RULE_OPTION, option);
+       item.set(NULL, CONTEXT_RULE_DATA, data);
+       result.array_append(NULL, CONTEXT_RULE_CONDITION, item);
+
+       if (result.array_get_size(NULL, CONTEXT_RULE_CONDITION) == (int) condition.size()) {
+               on_context_data_prepared(data);
+       }
+}
+
+void ctx::trigger_rule::clear_result()
+{
+       result = json();
+       // TODO timer cancel
+}
+
+void ctx::trigger_rule::on_context_data_prepared(ctx::json& data)
+{
+       if (ctx::rule_evaluator::evaluate_rule(statement, data)) {
+               ctx::action_manager::trigger_action(action, creator);
+       }
+
+       clear_result();
+}
diff --git a/src/context_trigger/rule.h b/src/context_trigger/rule.h
new file mode 100644 (file)
index 0000000..43b3109
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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_TRIGGER_RULE_H__
+#define __CONTEXT_TRIGGER_RULE_H__
+
+#include <string>
+#include <json.h>
+#include "context_listener_iface.h"
+
+namespace ctx {
+
+       class context_monitor;
+
+       class trigger_rule : public context_listener_iface {
+               private:
+                       struct context_item_s {
+                               std::string name;
+                               ctx::json option;
+                               context_item_s(ctx::json item) {
+                                       std::string n;
+                                       item.get(NULL, CT_RULE_EVENT_ITEM, &n);
+                                       name = n;
+
+                                       ctx::json o;
+                                       if (item.get(NULL, CT_RULE_EVENT_OPTION, &o))
+                                               option = o.str();
+                               }
+                       };
+
+                       typedef struct context_item_s* context_item_t;
+                       ctx::json statement;
+                       context_item_t event;
+                       std::list<context_item_t> condition;
+                       ctx::json action;
+                       ctx::json result;
+
+                       context_monitor* ctx_monitor;
+
+                       void clear_result(void);
+                       void on_context_data_prepared(ctx::json& data);
+
+               public:
+                       int id;
+                       std::string creator;
+
+                       trigger_rule();
+                       trigger_rule(int i, ctx::json& d, const char* c, context_monitor* cm);
+                       ~trigger_rule();
+
+                       int start(void);
+                       int stop(void);
+
+                       void on_event_received(std::string name, ctx::json option, ctx::json data);
+                       void on_condition_received(std::string name, ctx::json option, ctx::json data);
+
+       };
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_TRIGGER_RULE_H__ */
diff --git a/src/context_trigger/rule_evaluator.cpp b/src/context_trigger/rule_evaluator.cpp
new file mode 100644 (file)
index 0000000..7a9a65f
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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 <json.h>
+#include "rule_evaluator.h"
+
+bool ctx::rule_evaluator::evaluate_rule(ctx::json& rule, ctx::json& data)
+{
+       return true;
+}
diff --git a/src/context_trigger/rule_evaluator.h b/src/context_trigger/rule_evaluator.h
new file mode 100644 (file)
index 0000000..e116fc1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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_EVALUATOR_H__
+#define __CONTEXT_RULE_EVALUATOR_H__
+
+namespace ctx {
+
+       class json;
+
+       namespace rule_evaluator {
+
+               bool evaluate_rule(ctx::json& rule, ctx::json& data);
+
+       }
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_RULE_EVALUATOR_H__ */
index 588d7b14ebd059e2920d2fc8edaf8e12c78b500a..a4d8a44aefe18ee9e5b57105f940c39cd744c693 100644 (file)
  */
 
 #include <sstream>
-#include <app.h>
-#include <glib.h>
-#include <types_internal.h>
 #include <json.h>
-#include <stdlib.h>
-#include <bundle.h>
-#include <app_control.h>
-#include <appsvc.h>
-#include <app_control_internal.h>
-#include <device/display.h>
-#include <notification.h>
-#include <notification_internal.h>
-#include <runtime_info.h>
-#include <system_settings.h>
 #include <context_trigger_types_internal.h>
-#include <context_trigger.h>
 #include <db_mgr.h>
-#include "../dbus_server_impl.h"
 #include <app_manager.h>
 #include "rule_manager.h"
-#include "script_generator.h"
-#include "trigger.h"
+#include "context_monitor.h"
+#include "rule.h"
 
 #define RULE_TABLE "context_trigger_rule"
-#define EVENT_TABLE "context_trigger_event"
-#define CONDITION_TABLE "context_trigger_condition"
 #define TEMPLATE_TABLE "context_trigger_template"
 
 #define RULE_TABLE_COLUMNS "enabled INTEGER DEFAULT 0 NOT NULL, creator TEXT DEFAULT '' NOT NULL, creator_app_id TEXT DEFAULT '' NOT NULL, description TEXT DEFAULT '', details TEXT DEFAULT '' NOT NULL"
-#define EVENT_TABLE_COLUMNS "rule_id INTEGER references context_trigger_rule(row_id) ON DELETE CASCADE NOT NULL, name TEXT DEFAULT '' NOT NULL, instance_name TEXT DEFAULT ''"
-#define CONDITION_TABLE_COLUMNS "rule_id INTEGER references context_trigger_rule(row_id) ON DELETE CASCADE NOT NULL, name TEXT DEFAULT '' NOT NULL, option TEXT DEFAULT '', instance_name TEXT DEFAULT ''"
 #define CREATE_TEMPLATE_TABLE "CREATE TABLE IF NOT EXISTS context_trigger_template (name TEXT DEFAULT '' NOT NULL PRIMARY KEY, operation INTEGER DEFAULT 3 NOT NULL, attributes TEXT DEFAULT '' NOT NULL, options TEXT DEFAULT '' NOT NULL)"
-#define QUERY_TEMPLATE_TABLE "SELECT name, operation, attributes, options FROM context_trigger_template"
 #define FOREIGN_KEYS_ON "PRAGMA foreign_keys = ON"
 #define DELETE_RULE_STATEMENT "DELETE FROM 'context_trigger_rule' where row_id = "
 #define UPDATE_RULE_ENABLED_STATEMENT "UPDATE context_trigger_rule SET enabled = 1 WHERE row_id = "
 #define UPDATE_RULE_DISABLED_STATEMENT "UPDATE context_trigger_rule SET enabled = 0 WHERE row_id = "
-#define QUERY_NAME_INSTANCE_NAME_AND_ATTRIBUTES_BY_RULE_ID_STATEMENT "SELECT context_trigger_condition.name, instance_name, attributes FROM context_trigger_condition JOIN context_trigger_template ON (context_trigger_condition.name = context_trigger_template.name) WHERE rule_id = "
-#define QUERY_CONDITION_TEMPLATES_OF_INVOKED_EVENT_STATEMENT "SELECT DISTINCT context_trigger_condition.name, instance_name, option, attributes, options FROM context_trigger_condition JOIN context_trigger_template ON (context_trigger_condition.name = context_trigger_template.name) WHERE rule_id IN (SELECT row_id FROM context_trigger_rule WHERE enabled = 1 AND row_id IN (SELECT rule_id FROM context_trigger_event WHERE context_trigger_event.instance_name = '"
-#define QUERY_RULE_BY_RULE_ID "SELECT details FROM context_trigger_rule WHERE row_id = "
-#define QUERY_EVENT_TEMPLATE_BY_RULE_ID "SELECT name, attributes, options FROM context_trigger_template WHERE name IN (SELECT name FROM context_trigger_event WHERE rule_id = "
-#define QUERY_CONDITION_BY_RULE_ID "SELECT name, option FROM context_trigger_condition WHERE rule_id = "
+#define QUERY_RULE_AND_CREATOR_BY_RULE_ID "SELECT details, creator_app_id FROM context_trigger_rule WHERE row_id = "
 
 #define INSTANCE_NAME_DELIMITER "/"
-#define EVENT_KEY_PREFIX "?"
-
-static ctx::context_trigger* trigger = NULL;
-static int enb_rule_cnt = 0;
 
 static int string_to_int(std::string str)
 {
@@ -83,50 +55,27 @@ static std::string int_to_string(int i)
        return str;
 }
 
-static bool convert_str_to_json(ctx::json* val, const char* path, const char* key)
-{
-       // TODO:
-       IF_FAIL_RETURN(val, false);
-
-       std::string buf;
-       IF_FAIL_RETURN(val->get(path, key, &buf), false);
-
-       ctx::json temp = buf;
-       IF_FAIL_RETURN(val->set(path, key, temp), false);
-
-       return true;
-}
-
 ctx::rule_manager::rule_manager()
 {
 }
 
 ctx::rule_manager::~rule_manager()
 {
-       destroy_clips();
 }
 
-bool ctx::rule_manager::init(ctx::context_trigger* tr, ctx::context_manager_impl* ctx_mgr)
+bool ctx::rule_manager::init(ctx::context_manager_impl* ctx_mgr)
 {
        bool ret;
        int error;
 
-       clips_h = NULL;
-       trigger = tr;
-       ret = c_monitor.init(ctx_mgr, tr);
+       ret = ctx_monitor.init(ctx_mgr);
        IF_FAIL_RETURN_TAG(ret, false, _E, "Context monitor initialization failed");
 
        // Create tables into db (rule, event, condition, action, template)
        ret = db_manager::create_table(1, RULE_TABLE, RULE_TABLE_COLUMNS, NULL, NULL);
        IF_FAIL_RETURN_TAG(ret, false, _E, "Create rule table failed");
 
-       ret = db_manager::create_table(2, EVENT_TABLE, EVENT_TABLE_COLUMNS, NULL, NULL);
-       IF_FAIL_RETURN_TAG(ret, false, _E, "Create event table failed");
-
-       ret = db_manager::create_table(3, CONDITION_TABLE, CONDITION_TABLE_COLUMNS, NULL, NULL);
-       IF_FAIL_RETURN_TAG(ret, false, _E, "Create condition table failed");
-
-       ret = db_manager::execute(4, CREATE_TEMPLATE_TABLE, NULL);
+       ret = db_manager::execute(2, CREATE_TEMPLATE_TABLE, NULL);
        IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed");
 
        // Foreign keys on
@@ -136,6 +85,7 @@ bool ctx::rule_manager::init(ctx::context_trigger* tr, ctx::context_manager_impl
 
        apply_templates();
 
+       // Before re-enable rules, handle uninstalled app's rules
        if (get_uninstalled_app() > 0) {
                error = clear_rule_of_uninstalled_app(true);
                IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Failed to remove uninstalled apps' rules while initialization");
@@ -154,7 +104,7 @@ void ctx::rule_manager::apply_templates(void)
        std::string q_update;
        std::string q_insert = "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options) VALUES";
 
-       while (c_monitor.get_fact_definition(subject, operation, attributes, options)) {
+       while (ctx_monitor.get_fact_definition(subject, operation, attributes, options)) {
                _D("Subject: %s, Ops: %d", subject.c_str(), operation);
                _J("Attr", attributes);
                _J("Opt", options);
@@ -239,9 +189,9 @@ int ctx::rule_manager::clear_rule_of_uninstalled_app(bool is_init)
        }
        creator_list += ")";
 
-       // After event received, disable all the enabled rules of uninstalled apps
+       // After event received, disable all the enabled rules of uninstalled apps      // TODO register uninstalled apps app_id when before trigger
        if (!is_init) {
-               std::string q1 = "SELECT row_id, details FROM context_trigger_rule WHERE enabled = 1 and (";
+               std::string q1 = "SELECT row_id FROM context_trigger_rule WHERE enabled = 1 and (";
                q1 += creator_list;
                q1 += ")";
 
@@ -252,8 +202,10 @@ int ctx::rule_manager::clear_rule_of_uninstalled_app(bool is_init)
                std::vector<json>::iterator vec_end = record.end();
                for (std::vector<json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
                        ctx::json elem = *vec_pos;
-                       error = disable_uninstalled_rule(elem);
-                       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rules" );
+                       int rule_id;
+                       elem.get(NULL, "row_id", &rule_id);
+                       error = disable_rule(rule_id);
+                       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rule" );
                }
                _D("Uninstalled apps' rules are disabled");
        }
@@ -270,113 +222,6 @@ int ctx::rule_manager::clear_rule_of_uninstalled_app(bool is_init)
        return ERR_NONE;
 }
 
-int ctx::rule_manager::disable_uninstalled_rule(ctx::json& rule_info)
-{
-       int error;
-       bool ret;
-
-       int rule_id;
-       rule_info.get(NULL, "row_id", &rule_id);
-
-       // For event with options
-       std::string r1;
-       rule_info.get(NULL, "details", &r1);
-       ctx::json rule = r1;
-       ctx::json event;
-       rule.get(NULL, CT_RULE_EVENT, &event);
-       std::string ename;
-       event.get(NULL, CT_RULE_EVENT_ITEM, &ename);
-
-       // Unsubscribe event
-       error = c_monitor.unsubscribe(rule_id, ename, event);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Failed to unsubscribe %s of rule%d: %d", ename.c_str(), rule_id, error);
-
-       // Undef rule in clips
-       std::string id_str = int_to_string(rule_id);
-       std::string script = script_generator::generate_undefrule(id_str);
-       error = clips_h->route_string_command(script);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Failed to undefine rule%d: %d", rule_id, error);
-
-       // Remove condition instances
-       std::string q3 = "SELECT name, instance_name FROM context_trigger_condition WHERE rule_id = ";
-       q3 += id_str;
-       std::vector<json> name_record;
-       ret = db_manager::execute_sync(q3.c_str(), &name_record);
-       IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query condition table of rule%d failed: %d", rule_id, error);
-
-       std::vector<json>::iterator vec_end = name_record.end();
-       for (std::vector<json>::iterator vec_pos = name_record.begin(); vec_pos != vec_end; ++vec_pos) {
-               ctx::json elem = *vec_pos;
-
-               std::string cname;
-               std::string ciname;
-               elem.get(NULL, "name", &cname);
-               elem.get(NULL, "instance_name", &ciname);
-
-               if (cname.compare(ciname) != 0) {
-                       cond_cnt_map[ciname]--;
-
-                       if (cond_cnt_map[ciname] == 0) {
-                               error = clips_h->unmake_instance(ciname);
-                               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to unmake instance %s of rule%d: %d", ciname.c_str(), rule_id, error);
-
-                               cond_cnt_map.erase(ciname);
-                       }
-               }
-       }
-
-       if (--enb_rule_cnt <= 0) {
-               enb_rule_cnt = 0;
-               destroy_clips();
-       }
-       return ERR_NONE;
-}
-
-bool ctx::rule_manager::initialize_clips(void)
-{
-       if (clips_h) {
-               _D("CLIPS handler already initialized");
-               return true;
-       }
-
-       clips_h = new(std::nothrow) clips_handler(this);
-       IF_FAIL_RETURN_TAG(clips_h, false, _E, "CLIPS handler initialization failed");
-
-       // Load all templates from DB
-       std::vector<json> record;
-       bool ret = db_manager::execute_sync(QUERY_TEMPLATE_TABLE, &record);
-       IF_FAIL_RETURN_TAG(ret, false, _E, "Query template table failed");
-
-       // Make scripts for deftemplate, defclass, make-instance and load them to clips
-       std::vector<json>::iterator vec_end = record.end();
-       for (std::vector<json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
-               ctx::json tmpl = *vec_pos;
-               convert_str_to_json(&tmpl, NULL, "attributes");
-               convert_str_to_json(&tmpl, NULL, "options");
-
-               std::string deftemplate_str = script_generator::generate_deftemplate(tmpl);
-               int error = clips_h->define_template(deftemplate_str);
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Deftemplate failed");
-
-               std::string defclass_str = script_generator::generate_defclass(tmpl);
-               error = clips_h->define_class(defclass_str);
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Defclass failed");
-
-               std::string makeinstance_str = script_generator::generate_makeinstance(tmpl);
-               error = clips_h->make_instance(makeinstance_str);
-               IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Makeinstance failed");
-       }
-
-       _D(YELLOW("Deftemplate, Defclass, Make-instance completed"));
-       return true;
-}
-
-void ctx::rule_manager::destroy_clips(void)
-{
-       delete clips_h;
-       clips_h = NULL;
-}
-
 bool ctx::rule_manager::reenable_rule(void)
 {
        int error;
@@ -395,8 +240,6 @@ bool ctx::rule_manager::reenable_rule(void)
                error = enable_rule(row_id);
                if (error != ERR_NONE) {
                        _E("Re-enable rule%d failed(%d)", row_id, error);
-               } else {
-                       _D("Re-enable rule%d succeeded", row_id);
                }
        }
 
@@ -459,14 +302,11 @@ bool ctx::rule_manager::rule_item_equals(ctx::json& litem, ctx::json& ritem)
        if (lei.compare(rei))
                return false;
 
-       // Compare option
+       // Compare option       // TODO test
        ctx::json loption, roption;
-       std::string linst, rinst;
        litem.get(NULL, CT_RULE_EVENT_OPTION, &loption);
        ritem.get(NULL, CT_RULE_EVENT_OPTION, &roption);
-       linst = get_instance_name(lei, loption);
-       rinst = get_instance_name(rei, roption);
-       if (linst.compare(rinst))
+       if (loption != roption)
                return false;
 
        int ledac, redac;
@@ -616,10 +456,10 @@ int ctx::rule_manager::verify_rule(ctx::json& rule, const char* creator)
        std::string e_name;
        rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_ITEM, &e_name);
 
-       IF_FAIL_RETURN_TAG(c_monitor.is_supported(e_name), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", e_name.c_str());
+       IF_FAIL_RETURN_TAG(ctx_monitor.is_supported(e_name), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", e_name.c_str());
 
        if (creator) {
-               if (!c_monitor.is_allowed(creator, e_name.c_str())) {
+               if (!ctx_monitor.is_allowed(creator, e_name.c_str())) {
                        _W("Permission denied for '%s'", e_name.c_str());
                        return ERR_PERMISSION_DENIED;
                }
@@ -630,9 +470,9 @@ int ctx::rule_manager::verify_rule(ctx::json& rule, const char* creator)
                std::string c_name;
                it.get(NULL, CT_RULE_CONDITION_ITEM, &c_name);
 
-               IF_FAIL_RETURN_TAG(c_monitor.is_supported(c_name), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", c_name.c_str());
+               IF_FAIL_RETURN_TAG(ctx_monitor.is_supported(c_name), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", c_name.c_str());
 
-               if (!c_monitor.is_allowed(creator, c_name.c_str())) {
+               if (!ctx_monitor.is_allowed(creator, c_name.c_str())) {
                        _W("Permission denied for '%s'", c_name.c_str());
                        return ERR_PERMISSION_DENIED;
                }
@@ -643,7 +483,6 @@ int ctx::rule_manager::verify_rule(ctx::json& rule, const char* creator)
 
 int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::json rule, ctx::json* rule_id)
 {
-       // * Insert rule to DB
        bool ret;
        int64_t rid;
 
@@ -659,7 +498,7 @@ int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::js
                return ERR_NONE;
        }
 
-       // Insert rule to rule table, get rule id and save it to json parameter
+       // Insert rule to rule table, get rule id
        ctx::json r_record;
        std::string description;
        ctx::json details;
@@ -677,48 +516,6 @@ int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::js
        // Save rule id
        rule_id->set(NULL, CT_RULE_ID, rid);
 
-       // Insert event & conditions of a rule into each table
-       ctx::json e_record;
-       std::string e_name;
-       ctx::json e_option_j;
-       std::string e_inst;
-
-       rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_ITEM, &e_name);
-       rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_OPTION, &e_option_j);
-       e_inst = get_instance_name(e_name, e_option_j);
-
-       e_record.set(NULL, "rule_id", rid);
-       e_record.set(NULL, "name", e_name);
-       e_record.set(NULL, "instance_name", e_inst);
-       ret = db_manager::insert(1, EVENT_TABLE, e_record, NULL);
-       IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert event to db failed");
-
-       ctx::json it;
-       for (int i = 0; rule.get_array_elem(CT_RULE_DETAILS, CT_RULE_CONDITION, i, &it); i++){
-               ctx::json c_record;
-               std::string c_name;
-               ctx::json c_option;
-               char* c_option_str;
-               ctx::json tmp_option;
-               std::string c_inst;
-
-               it.get(NULL, CT_RULE_CONDITION_ITEM, &c_name);
-               it.get(NULL, CT_RULE_CONDITION_OPTION, &tmp_option);
-               c_inst = get_instance_name(c_name, tmp_option);
-               c_option.set(NULL, CT_RULE_CONDITION_OPTION, tmp_option);
-               c_option_str = c_option.dup_cstr();
-
-               c_record.set(NULL, "rule_id", rid);
-               c_record.set(NULL, "name", c_name);
-               c_record.set(NULL, "option", (c_option_str)? c_option_str : "");
-               c_record.set(NULL, "instance_name", c_inst);
-
-               ret = db_manager::insert(2, CONDITION_TABLE, c_record, NULL);
-               IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert conditions to db failed");
-
-               free(c_option_str);
-       }
-
        _D("Add rule%d succeeded", (int)rid);
        return ERR_NONE;
 }
@@ -726,9 +523,9 @@ int ctx::rule_manager::add_rule(std::string creator, const char* app_id, ctx::js
 
 int ctx::rule_manager::remove_rule(int rule_id)
 {
-       // Delete rule from DB
        bool ret;
 
+       // Delete rule from DB
        std::string query = DELETE_RULE_STATEMENT;
        query += int_to_string(rule_id);
        std::vector<json> record;
@@ -740,94 +537,34 @@ int ctx::rule_manager::remove_rule(int rule_id)
 
 int ctx::rule_manager::enable_rule(int rule_id)
 {
-       if (enb_rule_cnt == 0) {
-               IF_FAIL_RETURN_TAG(initialize_clips(), ERR_OPERATION_FAILED, _E, "Failed to init clips");
-       }
-
-       // Subscribe event
        int error;
        std::string query;
-       std::string ename;
-       std::string script;
-       std::string tmp;
-
-       ctx::json jrule;
-       ctx::json jetemplate;
-       ctx::json jevent;
-       ctx::json inst_names;
-
        std::vector<json> rule_record;
-       std::vector<json> etmpl_record;
-       std::vector<json> cond_record;
        std::vector<json> record;
-       std::vector<json>::iterator vec_end;
-
+       std::string creator_app_id;
+       ctx::json jrule;
+       std::string tmp;
        std::string id_str = int_to_string(rule_id);
 
+       trigger_rule* rule;
+
        // Get rule json by rule id;
-       query = QUERY_RULE_BY_RULE_ID;
-       query += int_to_string(rule_id);
+       query = QUERY_RULE_AND_CREATOR_BY_RULE_ID;
+       query += id_str;
        error = (db_manager::execute_sync(query.c_str(), &rule_record))? ERR_NONE : ERR_OPERATION_FAILED;
-       IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Query rule by rule id failed");
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Query rule by rule id failed");
 
        rule_record[0].get(NULL, "details", &tmp);
        jrule = tmp;
-       jrule.get(NULL, CT_RULE_EVENT, &jevent);
-
-       // Get event template by rule id
-       query = QUERY_EVENT_TEMPLATE_BY_RULE_ID;
-       query += int_to_string(rule_id);
-       query += ")";
-       error = (db_manager::execute_sync(query.c_str(), &etmpl_record))? ERR_NONE : ERR_OPERATION_FAILED;
-       IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Query event template by rule id failed");
-
-       jetemplate = etmpl_record[0].str();
-       convert_str_to_json(&jetemplate, NULL, "attributes");
-       convert_str_to_json(&jetemplate, NULL, "options");
-
-       // Query name, instance name & attributes for conditions of the rule
-       query = QUERY_NAME_INSTANCE_NAME_AND_ATTRIBUTES_BY_RULE_ID_STATEMENT;
-       query += id_str;
-       error = (db_manager::execute_sync(query.c_str(), &cond_record))? ERR_NONE : ERR_OPERATION_FAILED;
-       IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Query condition's names, instance names, attributes by rule id failed");
-
-       vec_end = cond_record.end();
-       for (std::vector<json>::iterator vec_pos = cond_record.begin(); vec_pos != vec_end; ++vec_pos) {
-               ctx::json elem = *vec_pos;
-
-               std::string cname;
-               std::string ciname;
-               elem.get(NULL, "name", &cname);
-               elem.get(NULL, "instance_name", &ciname);
-               convert_str_to_json(&elem, NULL, "attributes");
-
-               // For defrule script generation
-               inst_names.set(NULL, cname.c_str(), ciname);
-
-               if (cname.compare(ciname) != 0) {
-                       if (!clips_h->find_instance(ciname)) {
-                               std::string makeinst_script = script_generator::generate_makeinstance(elem);
-                               error = (makeinst_script.length() > 0)? ERR_NONE : ERR_OPERATION_FAILED;
-                               IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Make instance script generation failed");
-                               error = clips_h->make_instance(makeinst_script);
-                               IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Add condition instance([%s]) failed", ciname.c_str());
-
-                               cond_cnt_map[ciname] = 1;
-                       } else {
-                               cond_cnt_map[ciname]++;
-                       }
-               }
-       }
+       rule_record[0].get(NULL, "creator_app_id", &creator_app_id);
 
-       // Subscribe event
-       jetemplate.get(NULL, "name", &ename);
-       error = c_monitor.subscribe(rule_id, ename, jevent);
-       IF_FAIL_CATCH(error == ERR_NONE);
+       // Create a rule instance
+       rule = new(std::nothrow) trigger_rule(rule_id, jrule, creator_app_id.c_str(), &ctx_monitor);
+       IF_FAIL_RETURN_TAG(rule, ERR_OUT_OF_MEMORY, _E, "Failed to create rule instance");
 
-       // Generate defrule script and execute it
-       script = script_generator::generate_defrule(id_str, jetemplate, jrule, inst_names);
-       error = clips_h->define_rule(script);
-       IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Defrule failed");
+       // Start the rule
+       error = rule->start();
+       IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Failed to start rule%d", rule_id);
 
        // Update db to set 'enabled'
        query = UPDATE_RULE_ENABLED_STATEMENT;
@@ -835,445 +572,45 @@ int ctx::rule_manager::enable_rule(int rule_id)
        error = (db_manager::execute_sync(query.c_str(), &record))? ERR_NONE : ERR_OPERATION_FAILED;
        IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Update db failed");
 
-       enb_rule_cnt++;
-       _D(YELLOW("Enable Rule%d succeeded"), rule_id);
+       // Add rule instance to rule_map
+       rule_map[rule_id] = rule;
 
+       _D(YELLOW("Enable Rule%d succeeded"), rule_id);
        return ERR_NONE;
 
 CATCH:
-       if (enb_rule_cnt <= 0) {
-               enb_rule_cnt = 0;
-               destroy_clips();
-       }
+       delete rule;
+       rule = NULL;
 
        return error;
 }
 
-std::string ctx::rule_manager::get_instance_name(std::string name, ctx::json& option)
-{
-       std::string inst_name = name;
-       std::vector<json> record_tmpl;
-       ctx::json tmpl_c;
-       std::list<std::string> option_keys;
-
-       // Get template for the option
-       std::string q = "SELECT options FROM context_trigger_template WHERE name = '";
-       q += name;
-       q += "'";
-       db_manager::execute_sync(q.c_str(), &record_tmpl);
-
-       convert_str_to_json(&record_tmpl[0], NULL, "options");
-       record_tmpl[0].get(NULL, "options", &tmpl_c);
-
-       tmpl_c.get_keys(&option_keys);
-
-       for (std::list<std::string>::iterator it = option_keys.begin(); it != option_keys.end(); ++it) {
-               std::string key = (*it);
-               std::string val_str;
-               int val;
-
-               if (option.get(NULL, key.c_str(), &val_str)) {
-                       inst_name += INSTANCE_NAME_DELIMITER;
-                       inst_name += val_str;
-               } else if (option.get(NULL, key.c_str(), &val)) {
-                       inst_name += INSTANCE_NAME_DELIMITER;
-                       inst_name += int_to_string(val);
-               } else {
-                       inst_name += INSTANCE_NAME_DELIMITER;
-               }
-       }
-
-       return inst_name;
-}
-
 int ctx::rule_manager::disable_rule(int rule_id)
 {
-       int error;
        bool ret;
-
-       // For event with options
-       // Get rule json by rule id;
-       std::string q1 = QUERY_RULE_BY_RULE_ID;
-       q1 += int_to_string(rule_id);
-       std::vector<json> rule_record;
-       ret = db_manager::execute_sync(q1.c_str(), &rule_record);
-       IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query rule by rule id failed");
-       std::string r1;
-       rule_record[0].get(NULL, "details", &r1);
-       ctx::json rule = r1;
-       ctx::json event;
-       rule.get(NULL, CT_RULE_EVENT, &event);
-       std::string ename;
-       event.get(NULL, CT_RULE_EVENT_ITEM, &ename);
-
-       // Unsubscribe event
-       error = c_monitor.unsubscribe(rule_id, ename, event);
-       IF_FAIL_RETURN(error == ERR_NONE, ERR_OPERATION_FAILED);
-
-       // Undef rule in clips
-       std::string id_str = int_to_string(rule_id);
-       std::string script = script_generator::generate_undefrule(id_str);
-       error = clips_h->route_string_command(script);
-       IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Undefrule failed");
-
-       // Update db to set 'disabled'
-       std::string q2 = UPDATE_RULE_DISABLED_STATEMENT;
-       q2 += id_str;
-       std::vector<json> record;
-       ret = db_manager::execute_sync(q2.c_str(), &record);
-       IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
-
-       // Remove condition instances
-       std::string q3 = "SELECT name, instance_name FROM context_trigger_condition WHERE rule_id = ";
-       q3 += id_str;
-       std::vector<json> name_record;
-       ret = db_manager::execute_sync(q3.c_str(), &name_record);
-       IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query condition's name, instance names by rule id failed");
-
-       std::vector<json>::iterator vec_end = name_record.end();
-       for (std::vector<json>::iterator vec_pos = name_record.begin(); vec_pos != vec_end; ++vec_pos) {
-               ctx::json elem = *vec_pos;
-
-               std::string cname;
-               std::string ciname;
-               elem.get(NULL, "name", &cname);
-               elem.get(NULL, "instance_name", &ciname);
-
-               if (cname.compare(ciname) != 0) {
-                       cond_cnt_map[ciname]--;
-
-                       if (cond_cnt_map[ciname] == 0) {
-                               error = clips_h->unmake_instance(ciname);
-                               IF_FAIL_RETURN(error == ERR_NONE, error);
-
-                               cond_cnt_map.erase(ciname);
-                       }
-               }
-       }
-
-       if (--enb_rule_cnt <= 0) {
-               enb_rule_cnt = 0;
-               destroy_clips();
-       }
-       return ERR_NONE;
-}
-
-void ctx::rule_manager::make_condition_option_based_on_event_data(ctx::json& ctemplate, ctx::json& edata, ctx::json* coption)
-{
-       std::list<std::string> option_keys;
-       ctemplate.get_keys(&option_keys);
-
-       for (std::list<std::string>::iterator it = option_keys.begin(); it != option_keys.end(); ++it) {
-               std::string key = (*it);
-
-               std::string coption_valstr;
-               if (coption->get(NULL, key.c_str(), &coption_valstr)) {
-                       if (coption_valstr.find(EVENT_KEY_PREFIX) == 0) {
-                               std::string event_key = coption_valstr.substr(1, coption_valstr.length() - 1);
-
-                               std::string e_valstr;
-                               int e_val;
-                               if (edata.get(NULL, event_key.c_str(), &e_valstr)) {
-                                       coption->set(NULL, key.c_str(), e_valstr);
-                               } else if (edata.get(NULL, event_key.c_str(), &e_val)) {
-                                       coption->set(NULL, key.c_str(), e_val);
-                               }
-                       }
-               }
-       }
-}
-
-void ctx::rule_manager::on_event_received(std::string item, ctx::json option, ctx::json data)
-{
-       _D(YELLOW("Event(%s(%s) - %s) is invoked."), item.c_str(), option.str().c_str(), data.str().c_str());
-       // TODO: Check permission of an event(item), if permission denied, return
-
-       int err;
-       bool ret;
-
-       // Generate event fact script
-       std::string q1 = "SELECT attributes, options FROM context_trigger_template WHERE name = '";
-       q1 += item;
-       q1 += "'";
-       std::vector<json> etemplate_record;
-       db_manager::execute_sync(q1.c_str(), &etemplate_record);
-
-       ctx::json etemplate = etemplate_record[0];
-       convert_str_to_json(&etemplate, NULL, "attributes");
-       convert_str_to_json(&etemplate, NULL, "options");
-
-       std::string eventfact_str = script_generator::generate_fact(item, etemplate, option, data);
-
-       // Get Conditions template of invoked event (db query)
-       std::string e_inst = get_instance_name(item, option);
-       std::string query = QUERY_CONDITION_TEMPLATES_OF_INVOKED_EVENT_STATEMENT;
-       query += e_inst;
-       query += "'))";
-       std::vector<json> conds;
-       ret = db_manager::execute_sync(query.c_str(), &conds);
-       IF_FAIL_VOID_TAG(ret, _E, "Query condition templates of invoked event failed");
-
-       int cond_num = conds.size();
-       for (int i = 0; i < cond_num; i++) {
-               convert_str_to_json(&conds[i], NULL, "options");
-               convert_str_to_json(&conds[i], NULL, "attributes");
-
-               std::string cname;
-               conds[i].get(NULL, "name", &cname);
-
-               std::string ciname;
-               conds[i].get(NULL, "instance_name", &ciname);
-
-               std::string coption_str;
-               conds[i].get(NULL, "option", &coption_str);
-               ctx::json coption = NULL;
-               if (!coption_str.empty()) {
-                       ctx::json coption_tmp = coption_str;
-                       coption_tmp.get(NULL, CT_RULE_CONDITION_OPTION, &coption);
-               }
-
-               // Check if the condition uses event data key as an option
-               if (ciname.find(EVENT_KEY_PREFIX) != std::string::npos) {
-                       make_condition_option_based_on_event_data(conds[i], data, &coption);    //TODO: conds[i] -> "options"
-               }
-
-               // TODO: Check permission of a condition(cname), if permission granted, read condition data. (or, condition data should be empty json)
-
-               //      Get Context Data
-               ctx::json condition_data;
-               err = c_monitor.read(cname, coption, &condition_data);
-               if (err != ERR_NONE)
-                       return;
-               _D(YELLOW("Condition(%s(%s) - %s)."), cname.c_str(), coption.str().c_str(), condition_data.str().c_str());
-
-               // Generate ModifyInstance script       // TODO: conds[i] => "attributes"
-               std::string modifyinst_script = script_generator::generate_modifyinstance(ciname, conds[i], condition_data);
-
-               err = clips_h->route_string_command(modifyinst_script);
-               IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Modify condition instance failed");
-       }
-
-       // Add fact and Run environment
-       err = clips_h->add_fact(eventfact_str);
-       IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Assert event fact failed");
-
-       err = clips_h->run_environment();
-       IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Run environment failed");
-
-       // Retract event fact
-       std::string retract_command = "(retract *)";
-       err = clips_h->route_string_command(retract_command);
-       IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Retract event fact failed");
-
-       // Clear uninstalled apps' rules if triggered
-       if (uninstalled_apps.size() > 0) {
-               err = clear_rule_of_uninstalled_app();
-               IF_FAIL_VOID_TAG(err == ERR_NONE, _E, "Failed to clear uninstalled apps' rules");
-       }
-}
-
-static void trigger_action_app_control(ctx::json& action)
-{
        int error;
-       std::string appctl_str;
-       action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str);
 
-       char* str = static_cast<char*>(malloc(appctl_str.length()));
-       if (str == NULL) {
-               _E("Memory allocation failed");
-               return;
-       }
-       appctl_str.copy(str, appctl_str.length(), 0);
-       bundle_raw* encoded = reinterpret_cast<unsigned char*>(str);
-       bundle* appctl_bundle = bundle_decode(encoded, appctl_str.length());
+       rule_map_t::iterator it = rule_map.find(rule_id);
+       IF_FAIL_RETURN_TAG(it != rule_map.end(), ERR_OPERATION_FAILED, _E, "Rule instance not found");
 
-       app_control_h app = NULL;
-       app_control_create(&app);
-       app_control_import_from_bundle(app, appctl_bundle);
+       // Stop the rule
+       trigger_rule* rule = static_cast<trigger_rule*>(it->second);
+       error = rule->stop();
+       IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", rule_id);
 
-       error = app_control_send_launch_request(app, NULL, NULL);
-       if (error != APP_CONTROL_ERROR_NONE) {
-               _E("Launch request failed(%d)", error);
-       } else {
-               _D("Launch request succeeded");
-       }
-       bundle_free(appctl_bundle);
-       free(str);
-       app_control_destroy(app);
-
-       error = device_display_change_state(DISPLAY_STATE_NORMAL);
-       if (error != DEVICE_ERROR_NONE) {
-               _E("Change display state failed(%d)", error);
-       }
-}
-
-static void trigger_action_notification(ctx::json& action, std::string app_id)
-{
-       int error;
-       notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI);
-       std::string title;
-       if (action.get(NULL, CT_RULE_ACTION_NOTI_TITLE, &title)) {
-               error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_TITLE, title.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
-               if (error != NOTIFICATION_ERROR_NONE) {
-                       _E("Set notification title failed(%d)", error);
-               }
-       }
-
-       std::string content;
-       if (action.get(NULL, CT_RULE_ACTION_NOTI_CONTENT, &content)) {
-               error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_CONTENT, content.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
-               if (error != NOTIFICATION_ERROR_NONE) {
-                       _E("Set notification contents failed(%d)", error);
-               }
-       }
-
-       std::string image_path;
-       if (action.get(NULL, CT_RULE_ACTION_NOTI_ICON_PATH, &image_path)) {
-               error = notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, image_path.c_str());
-               if (error != NOTIFICATION_ERROR_NONE) {
-                       _E("Set notification icon image failed(%d)", error);
-               }
-       }
-
-       std::string appctl_str;
-       char* str = NULL;
-       bundle_raw* encoded = NULL;
-       bundle* appctl_bundle = NULL;
-       app_control_h app = NULL;
-       if (action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str)) {
-               str = static_cast<char*>(malloc(appctl_str.length()));
-               if (str == NULL) {
-                       _E("Memory allocation failed");
-                       notification_free(notification);
-                       return;
-               }
-               appctl_str.copy(str, appctl_str.length(), 0);
-               encoded = reinterpret_cast<unsigned char*>(str);
-               appctl_bundle = bundle_decode(encoded, appctl_str.length());
-
-               app_control_create(&app);
-               app_control_import_from_bundle(app, appctl_bundle);
-
-               error = notification_set_launch_option(notification, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, app);
-               if (error != NOTIFICATION_ERROR_NONE) {
-                       _E("Set launch option failed(%d)", error);
-               }
-       }
-
-       if (!app_id.empty()) {
-               error = notification_set_pkgname(notification, app_id.c_str());
-               if (error != NOTIFICATION_ERROR_NONE) {
-                       _E("Set pkgname(%s) failed(%d)", app_id.c_str(), error);
-               }
-       }
-
-       bool silent = true;
-       error = system_settings_get_value_bool(SYSTEM_SETTINGS_KEY_SOUND_SILENT_MODE, &silent);
-       if (error != SYSTEM_SETTINGS_ERROR_NONE) {
-               _E("Get system setting(silent mode) failed(%d)", error);
-       }
-
-       bool vibration = true;
-       error = runtime_info_get_value_bool(RUNTIME_INFO_KEY_VIBRATION_ENABLED, &vibration);
-       if (error != RUNTIME_INFO_ERROR_NONE) {
-               _E("Get runtime info(vibration) failed(%d)", error);
-       }
-
-       if (!silent) {
-           error = notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL);
-               if (error != NOTIFICATION_ERROR_NONE) {
-                       _E("Set notification sound failed(%d)", error);
-               }
-
-               if (vibration) {
-                       error = notification_set_vibration(notification, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL);
-                       if (error != NOTIFICATION_ERROR_NONE) {
-                               _E("Set notification vibration failed(%d)", error);
-                       }
-               }
-       }
-
-       error = notification_post(notification);
-       if (error != NOTIFICATION_ERROR_NONE) {
-               _E("Post notification failed(%d)", error);
-       } else {
-               _D("Post notification succeeded");
-       }
-
-       bundle_free(appctl_bundle);
-       free(str);
-       notification_free(notification);
-       if (app) {
-               app_control_destroy(app);
-       }
-
-       error = device_display_change_state(DISPLAY_STATE_NORMAL);
-       if (error != DEVICE_ERROR_NONE) {
-               _E("Change display state failed(%d)", error);
-       }
-}
-
-static void trigger_action_dbus_call(ctx::json& action)
-{
-       std::string bus_name, object, iface, method;
-       GVariant *param = NULL;
-
-       action.get(NULL, CT_RULE_ACTION_DBUS_NAME, &bus_name);
-       IF_FAIL_VOID_TAG(!bus_name.empty(), _E, "No target bus name");
-
-       action.get(NULL, CT_RULE_ACTION_DBUS_OBJECT, &object);
-       IF_FAIL_VOID_TAG(!object.empty(), _E, "No object path");
-
-       action.get(NULL, CT_RULE_ACTION_DBUS_INTERFACE, &iface);
-       IF_FAIL_VOID_TAG(!iface.empty(), _E, "No interface name");
-
-       action.get(NULL, CT_RULE_ACTION_DBUS_METHOD, &method);
-       IF_FAIL_VOID_TAG(!method.empty(), _E, "No method name");
-
-       action.get(NULL, CT_RULE_ACTION_DBUS_PARAMETER, &param);
-
-       ctx::dbus_server::call(bus_name.c_str(), object.c_str(), iface.c_str(), method.c_str(), param);
-}
-
-void ctx::rule_manager::on_rule_triggered(int rule_id)
-{
-       std::string q = "SELECT details, creator_app_id FROM context_trigger_rule WHERE row_id =";
-       q += int_to_string(rule_id);
+       // Update db to set 'disabled'  // TODO skip while clear uninstalled rule
+       std::string query = UPDATE_RULE_DISABLED_STATEMENT;
+       query += int_to_string(rule_id);
        std::vector<json> record;
-       db_manager::execute_sync(q.c_str(), &record);
-       if (record.empty()) {
-               _E("Rule%d not exist", rule_id);
-               return;
-       }
+       ret = db_manager::execute_sync(query.c_str(), &record);
+       IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
 
-       // If rule's creator is uninstalled, skip action
-       std::string app_id;
-       record[0].get(NULL, "creator_app_id", &app_id);
-       if (is_uninstalled_package(app_id)) {
-               _D(YELLOW("Rule%d's creator(%s) is uninstalled. Skip action."), rule_id, app_id.c_str());
-               uninstalled_apps.insert(app_id);
-               return;
-       }
+       // Remove rule instance from rule_map
+       delete rule;
+       rule_map.erase(it);
 
-       _D(YELLOW("Rule%d is triggered"), rule_id);
-
-       // Do action
-       std::string details_str;
-       record[0].get(NULL, "details", &details_str);
-       ctx::json details = details_str;
-       ctx::json action;
-       details.get(NULL, CT_RULE_ACTION, &action);
-
-       std::string type;
-       if (action.get(NULL, CT_RULE_ACTION_TYPE, &type)) {
-               if (type.compare(CT_RULE_ACTION_TYPE_APP_CONTROL) == 0) {
-                       trigger_action_app_control(action);
-               } else if (type.compare(CT_RULE_ACTION_TYPE_NOTIFICATION) == 0) {
-                       trigger_action_notification(action, app_id);
-               } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) {
-                       trigger_action_dbus_call(action);
-               }
-       }
+       _D(YELLOW("Disable Rule%d succeeded"), rule_id);
+       return ERR_NONE;
 }
 
 int ctx::rule_manager::check_rule(std::string creator, int rule_id)
index 8a83ccd9193fd8dc60bef23b2e23d7a56e027803..dc200cce775e3b93a2230460849d6f837e294c8d 100644 (file)
 #define __RULE_MANAGER_H__
 
 #include <set>
-#include "clips_handler.h"
+#include <map>
 #include "context_monitor.h"
 
 namespace ctx {
 
        class json;
        class context_trigger;
+       class context_manager_impl;
+       class context_monitor;
+       class trigger_rule;
 
        class rule_manager {
                public:
                        rule_manager();
                        ~rule_manager();
-                       bool init(ctx::context_trigger* tr, ctx::context_manager_impl* ctx_mgr);
+                       bool init(ctx::context_manager_impl* ctx_mgr);
                        int add_rule(std::string creator, const char* app_id, ctx::json rule, ctx::json* rule_id);
                        int remove_rule(int rule_id);
                        int enable_rule(int rule_id);
@@ -40,12 +43,8 @@ namespace ctx {
                        int check_rule(std::string creator, int rule_id);
                        bool is_rule_enabled(int rule_id);
 
-                       void on_event_received(std::string item, ctx::json option, ctx::json data);
-                       void on_rule_triggered(int rule_id);
-
                private:
-                       clips_handler* clips_h;
-                       context_monitor c_monitor;
+                       ctx::context_monitor ctx_monitor;
 
                        void apply_templates(void);
                        bool reenable_rule(void);
@@ -54,17 +53,14 @@ namespace ctx {
                        bool rule_data_arr_elem_equals(ctx::json& lelem, ctx::json& relem);
                        bool rule_item_equals(ctx::json& litem, ctx::json& ritem);
                        bool rule_equals(ctx::json& lrule, ctx::json& rrule);
-                       std::string get_instance_name(std::string name, ctx::json& condition);
-                       void make_condition_option_based_on_event_data(ctx::json& ctemplate, ctx::json& edata, ctx::json* coption);
                        int get_uninstalled_app(void);
                        bool is_uninstalled_package(std::string app_id);
                        int clear_rule_of_uninstalled_app(bool is_init = false);
-                       int disable_uninstalled_rule(ctx::json& rule_info);
-                       bool initialize_clips(void);
-                       void destroy_clips(void);
 
-                       std::map<std::string, int> cond_cnt_map; // <condition instance name, count>
                        std::set<std::string> uninstalled_apps;
+
+                       typedef std::map<int, trigger_rule*> rule_map_t;
+                       rule_map_t rule_map;
    };  /* class rule_manager */
 
 }      /* namespace ctx */
diff --git a/src/context_trigger/script_generator.cpp b/src/context_trigger/script_generator.cpp
deleted file mode 100644 (file)
index fd2ee72..0000000
+++ /dev/null
@@ -1,513 +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 <set>
-#include <glib.h>
-#include <string>
-#include <json.h>
-#include <types_internal.h>
-#include <context_trigger_types_internal.h>
-#include "script_generator.h"
-#include "timer_types.h"
-
-#define EVENT_WEEKDAY "(or (eq ?DayOfWeek \"Mon\") (eq ?DayOfWeek \"Tue\") (eq ?DayOfWeek \"Wed\") (eq ?DayOfWeek \"Thu\") (eq ?DayOfWeek \"Fri\"))"
-#define EVENT_WEEKEND "(or (eq ?DayOfWeek \"Sat\") (eq ?DayOfWeek \"Sun\"))"
-#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\"))"
-#define CONDITION_WEEKEND "(or (eq (send [%s] get-DayOfWeek) \"Sat\") (eq (send [%s] get-DayOfWeek) \"Sun\"))"
-
-static std::string generate_initial_fact(ctx::json& event_tmpl, ctx::json& option);
-static std::string generate_event_data(ctx::json& event);
-static std::string generate_condition_data(std::string rule_id, ctx::json& conditions, std::string rule_op, ctx::json& inst_names);
-
-static std::string int_to_string(int i)
-{
-       std::ostringstream convert;
-       convert << i;
-       std::string str = convert.str();
-       return str;
-}
-
-static std::string convert_condition_weekday_weekend(std::string inst_name, std::string day)
-{
-       std::string buf = (day.compare(TIMER_WEEKDAY) == 0)? CONDITION_WEEKDAY : CONDITION_WEEKEND;
-
-       size_t pos = 0;
-       while ((pos = buf.find("%s", pos)) != std::string::npos) {
-               buf.replace(pos, 2, inst_name);
-               pos += inst_name.length();
-       }
-
-       return buf;
-}
-
-std::string ctx::script_generator::generate_deftemplate(ctx::json& tmpl)
-{
-       std::string script;
-       std::string name;
-       ctx::json attrs;
-       ctx::json options;
-       std::list<std::string> attr_keys;
-       std::list<std::string> option_keys;
-       std::set<std::string> slot;
-
-       tmpl.get(NULL, "name", &name);
-       tmpl.get(NULL, "attributes", &attrs);
-       tmpl.get(NULL, "options", &options);
-
-       attrs.get_keys(&attr_keys);
-       options.get_keys(&option_keys);
-
-       for (std::list<std::string>::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) {
-               slot.insert(*it);
-       }
-
-       for (std::list<std::string>::iterator it = option_keys.begin(); it != option_keys.end(); ++it) {
-               slot.insert(*it);
-       }
-
-       //template name is "itemname"
-       script = "(deftemplate ";
-       script += name;
-       script += " ";
-
-       for (std::set<std::string>::iterator it = slot.begin(); it != slot.end(); ++it){
-               script += "(slot ";
-               script += *it;
-               script += " (default nil))";
-       }
-       script += ")\n";
-
-       return script;
-}
-
-std::string ctx::script_generator::generate_defclass(ctx::json& tmpl)
-{
-       std::string script;
-       std::string name;
-       ctx::json attrs;
-       std::list<std::string> attr_keys;
-
-       tmpl.get(NULL, "name", &name);
-       tmpl.get(NULL, "attributes", &attrs);
-
-       attrs.get_keys(&attr_keys);
-
-       //class name is "C.itemname"
-       script = "(defclass C.";
-       script += name;
-       script += " (is-a USER) (role concrete) ";
-
-       for (std::list<std::string>::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) {
-               script += "(slot " + (*it) + " (default nil)(create-accessor read-write))";
-       }
-       script += ")\n";
-
-       return script;
-}
-
-std::string ctx::script_generator::generate_makeinstance(ctx::json& tmpl)
-{
-       std::string script;
-       std::string name;
-       ctx::json attrs;
-       std::list<std::string> attr_keys;
-
-       tmpl.get(NULL, "name", &name);
-       tmpl.get(NULL, "attributes", &attrs);
-
-       attrs.get_keys(&attr_keys);
-
-       std::string instance_name;
-       if (!tmpl.get(NULL, "instance_name", &instance_name)) {
-               // For default instance w/o option
-               instance_name = name;
-       }
-
-       //instance name is "[itemname]"
-       script = "([" + instance_name + "] of C." + name;
-
-       for (std::list<std::string>::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) {
-               script += " (" + (*it) + " 0)";
-       }
-       script += ")\n";
-
-       return script;
-}
-
-std::string ctx::script_generator::generate_undefrule(std::string rule_id)
-{
-       std::string script;
-       script = "(undefrule rule";
-       script += rule_id;
-       script += ")";
-
-       return script;
-}
-
-std::string ctx::script_generator::generate_defrule(std::string rule_id, ctx::json& event_tmpl, ctx::json& rule, ctx::json& inst_names)
-{
-       std::string script;
-       ctx::json option = NULL;
-       rule.get(CT_RULE_EVENT, CT_RULE_EVENT_OPTION, &option);
-
-       script = "(defrule rule" + rule_id + " ";
-       script += generate_initial_fact(event_tmpl, option);
-       script += " => ";
-
-       int eventdata_num = rule.array_get_size(CT_RULE_EVENT, CT_RULE_DATA_ARR);
-       int condition_num = rule.array_get_size(NULL, CT_RULE_CONDITION);
-
-       if (condition_num > 0) {
-               // case1: condition exists
-               script += "(if ";
-
-               if (eventdata_num > 0) {
-                       ctx::json event;
-                       rule.get(NULL, CT_RULE_EVENT, &event);
-                       script += "(and ";
-                       script += generate_event_data(event);
-               }
-
-               // condition
-               ctx::json conditions;
-               rule.get(NULL, CT_RULE_CONDITION, &conditions);
-               std::string rule_op;
-               rule.get(NULL, CT_RULE_OPERATOR, &rule_op);
-               script += generate_condition_data(rule_id, conditions, rule_op, inst_names);
-
-               if (eventdata_num > 0)
-                       script += ")";
-
-               script = script + " then (execute_action rule" + rule_id + "))";
-       } else if (eventdata_num > 0) {
-               // case2: no conditions, but event data
-               ctx::json event;
-               rule.get(NULL, CT_RULE_EVENT, &event);
-
-               script += "(if ";
-               script += generate_event_data(event);
-               script = script + " then (execute_action rule" + rule_id + "))";
-       } else {
-               // case3: only action
-               script = script + " (execute_action rule" + rule_id + ")";
-       }
-
-       script += ")";
-       _D("Defrule script generated: %s", script.c_str());
-       return script;
-}
-
-std::string generate_initial_fact(ctx::json& event_tmpl, ctx::json& option)
-{
-       std::string script;
-       std::string e_name;
-       ctx::json attrs;
-       ctx::json options;
-       std::list<std::string> attr_keys;
-       std::list<std::string> option_keys;
-
-       event_tmpl.get(NULL, "name", &e_name);
-       event_tmpl.get(NULL, "attributes", &attrs);
-       event_tmpl.get(NULL, "options", &options);
-
-       attrs.get_keys(&attr_keys);
-       options.get_keys(&option_keys);
-
-       script += "(" + e_name + " ";
-       // options
-       for (std::list<std::string>::iterator it = option_keys.begin(); it != option_keys.end(); ++it) {
-               std::string opt_key = (*it);
-               script += "(" + opt_key + " ";
-
-               std::string val_str;
-               int val;
-               if (option.get(NULL, opt_key.c_str(), &val_str)) {
-                       script += val_str;
-               } else if (option.get(NULL, opt_key.c_str(), &val)) {
-                       script += int_to_string(val);
-               } else {
-                       script += "?" + opt_key;
-               }
-               script += ")";
-       }
-
-       // attributes
-       for (std::list<std::string>::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) {
-               std::string attr_key = (*it);
-               script += "(" + attr_key + " ?" + attr_key + ")";
-       }
-       script += ")";
-
-       return script;
-}
-
-std::string generate_event_data(ctx::json& event)
-{
-       std::string ename;
-       event.get(NULL, CT_RULE_EVENT_ITEM, &ename);
-
-       std::string script;
-       int edata_count = event.array_get_size(NULL, CT_RULE_DATA_ARR);
-
-       if (edata_count > 1) {
-               std::string item_op;
-               event.get(NULL, CT_RULE_EVENT_OPERATOR, &item_op);
-               script += "(";
-               script += item_op;
-               script += " ";
-       }
-
-       ctx::json edata;
-       for (int i = 0; event.get_array_elem(NULL, CT_RULE_DATA_ARR, i, &edata); i++) {
-               std::string key_name;
-               if (ename.compare(TIMER_EVENT_SUBJECT) == 0) {
-                       edata.get(NULL, CT_RULE_DATA_KEY, &key_name);
-               }
-
-               int valuecount = edata.array_get_size(NULL, CT_RULE_DATA_VALUE_ARR);
-               int opcount = edata.array_get_size(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
-               std::string key;
-               edata.get(NULL, CT_RULE_DATA_KEY, &key);
-
-               if (valuecount != opcount) {
-                       _E("Invalid event data. (Value count:%d, Operator count: %d)", valuecount, opcount);
-                       return "";
-               }
-
-               if (valuecount > 1) {
-                       script += "(";
-
-                       std::string key_op;
-                       edata.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &key_op);
-                       script += key_op;
-                       script += " ";
-               }
-
-               for (int j = 0; j < valuecount; j++){
-                       std::string val_op;
-                       std::string val;
-                       edata.get_array_elem(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, j, &val_op);
-                       edata.get_array_elem(NULL, CT_RULE_DATA_VALUE_ARR, j, &val);
-
-                       if (key_name.compare(TIMER_RESPONSE_KEY_DAY_OF_WEEK) == 0) {
-                               if (val.compare("\"" TIMER_WEEKDAY "\"") == 0) {
-                                       script += (val_op.compare("eq") == 0)? EVENT_WEEKDAY : EVENT_WEEKEND;
-                                       continue;
-                               } else if (val.compare("\"" TIMER_WEEKEND "\"") == 0) {
-                                       script += (val_op.compare("eq") == 0)? EVENT_WEEKEND : EVENT_WEEKDAY;
-                                       continue;
-                               }
-                       }
-
-                       script += "(";
-                       script += val_op;
-                       script += " ?";
-                       script += key;
-                       script += " ";
-                       script += val;
-                       script += ")";
-               }
-
-               if (valuecount > 1) {
-                       script += ")";
-               }
-       }
-
-       if (edata_count > 1) {
-               script += ")";
-       }
-
-       return script;
-}
-
-std::string generate_condition_data(std::string rule_id, ctx::json& conditions, std::string rule_op, ctx::json& inst_names)
-{
-       std::string script;
-
-       ctx::json conds;
-       conds.set(NULL, CT_RULE_CONDITION, conditions);
-
-       int conds_count = conds.array_get_size(NULL, CT_RULE_CONDITION);
-       if (conds_count > 1) {
-               script += "(";
-               script += rule_op;      // operator between each condition item
-               script += " ";
-       }
-
-       ctx::json it;
-       for (int i = 0; conds.get_array_elem(NULL, CT_RULE_CONDITION, i, &it); i++) {
-               std::string cond_name;
-               it.get(NULL, CT_RULE_CONDITION_ITEM, &cond_name);
-
-               std::string inst_name;
-               inst_names.get(NULL, cond_name.c_str(), &inst_name);
-
-               int data_count = it.array_get_size(NULL, CT_RULE_DATA_ARR);
-
-               if (data_count > 1) {
-                       std::string item_op;
-                       it.get(NULL, CT_RULE_CONDITION_OPERATOR, &item_op);
-                       script += "(";
-                       script += item_op; // operator between data keys of a condition item
-                       script += " ";
-               }
-
-               ctx::json data;
-               for (int j = 0; it.get_array_elem(NULL, CT_RULE_DATA_ARR, j, &data); j++) {
-                       std::string key_name;
-                       data.get(NULL, CT_RULE_DATA_KEY, &key_name);
-                       int dval_count = data.array_get_size(NULL, CT_RULE_DATA_VALUE_ARR);
-                       int dvalop_count = data.array_get_size(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
-
-                       if (dval_count != dvalop_count) {
-                               _E("Invalid condition data. (Data value count %d, Data value operator count %d)", dval_count, dvalop_count);
-                       }
-
-                       if (dval_count > 1) {
-                               std::string dkey_op;
-                               data.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &dkey_op);
-
-                               script += "(";
-                               script += dkey_op; // operator between comparison data values of a condition data key
-                               script += " " ;
-                       }
-
-                       for (int k = 0; k < dval_count; k++) {
-                               std::string dval_op;
-                               std::string dval;
-                               data.get_array_elem(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, k, &dval_op);
-                               data.get_array_elem(NULL, CT_RULE_DATA_VALUE_ARR, k, &dval);
-
-                               if (inst_name.compare(TIMER_CONDITION_SUBJECT) == 0 && key_name.compare(TIMER_RESPONSE_KEY_DAY_OF_WEEK) == 0) {
-                                       if (dval.compare("\"" TIMER_WEEKDAY "\"") == 0) {
-                                               script += convert_condition_weekday_weekend(inst_name, (dval_op.compare("eq") == 0)? TIMER_WEEKDAY : TIMER_WEEKEND);
-                                               continue;
-                                       } else if (dval.compare("\"" TIMER_WEEKEND "\"") == 0) {
-                                               script += convert_condition_weekday_weekend(inst_name, (dval_op.compare("eq") == 0)? TIMER_WEEKEND : TIMER_WEEKDAY);
-                                               continue;
-                                       }
-                               }
-
-                               script += "(";
-                               script += dval_op;
-                               script += " (send [";
-                               script += inst_name;
-                               script += "] get-";
-                               script += key_name;
-                               script += ") ";
-                               script += dval;
-                               script += ")";
-                       }
-
-                       if (dval_count > 1) {
-                               script += ")";
-                       }
-               }
-
-               if (data_count > 1 ) {
-                       script += ")";
-               }
-       }
-
-       if (conds_count > 1) {
-               script += ")";
-       }
-
-       return script;
-}
-
-std::string ctx::script_generator::generate_fact(std::string item_name, ctx::json& event_tmpl, ctx::json& option, ctx::json& data)
-{
-       // Generate Fact script for invoked event
-       std::string script = "(" + item_name + " ";
-       ctx::json attrs;
-       ctx::json options;
-       std::list<std::string> attr_keys;
-       std::list<std::string> option_keys;
-
-       event_tmpl.get(NULL, "attributes", &attrs);
-       event_tmpl.get(NULL, "options", &options);
-
-       attrs.get_keys(&attr_keys);
-       options.get_keys(&option_keys);
-
-       for (std::list<std::string>::iterator it = option_keys.begin(); it != option_keys.end(); ++it) {
-               std::string opt_key = (*it);
-               std::string val_str;
-               int value;
-
-               script += "(" + opt_key + " ";
-
-               if (option.get(NULL, opt_key.c_str(), &val_str)) {      // string type data
-                       script += val_str;
-               } else if (option.get(NULL, opt_key.c_str(), &value)) { // integer type data
-                       script += int_to_string(value);
-               } else {
-                       script += "nil";
-               }
-               script += ")";
-       }
-
-       for (std::list<std::string>::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) {
-               std::string attr_key = (*it);
-               std::string val_str;
-               int value;
-
-               script += "(" + attr_key + " ";
-               if (data.get(NULL, attr_key.c_str(), &val_str)) {       // string type data
-                       script += "\"" + val_str + "\"";
-               } else if (data.get(NULL, attr_key.c_str(), &value)) {  // integer type data
-                       script += int_to_string(value);
-               } else {
-                       script += "nil";
-               }
-               script += ")";
-       }
-       script += ")";
-
-       return script;
-}
-
-std::string ctx::script_generator::generate_modifyinstance(std::string instance_name, ctx::json& cond_tmpl, ctx::json& data)
-{
-       std::string script = "(modify-instance [" + instance_name + "] ";
-       ctx::json attrs;
-       std::list<std::string> attr_keys;
-
-       cond_tmpl.get(NULL, "attributes", &attrs);
-       attrs.get_keys(&attr_keys);
-
-       // attributes
-       for (std::list<std::string>::iterator it = attr_keys.begin(); it != attr_keys.end(); ++it) {
-               std::string attr_key = (*it);
-               std::string val_str;
-               int value;
-
-               script += "(" + attr_key + " ";
-               if (data.get(NULL, attr_key.c_str(), &val_str)) {       // string type data
-                       script += "\"" + val_str + "\"";
-               } else  if (data.get(NULL, attr_key.c_str(), &value)) { // integer type data
-                       script += int_to_string(value);
-               } else {
-                       script += "nil";
-               }
-               script += ")";
-       }
-       script += ")";
-
-       return script;
-}
diff --git a/src/context_trigger/script_generator.h b/src/context_trigger/script_generator.h
deleted file mode 100644 (file)
index 4b2d1ac..0000000
+++ /dev/null
@@ -1,36 +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_SCRIPT_GENERATOR_H__
-#define __CONTEXT_SCRIPT_GENERATOR_H__
-
-namespace ctx {
-
-       namespace script_generator {
-
-               std::string generate_deftemplate(ctx::json& tmpl);
-               std::string generate_defclass(ctx::json& tmpl);
-               std::string generate_makeinstance(ctx::json& tmpl);
-               std::string generate_undefrule(std::string rule_id);
-               std::string generate_defrule(std::string rule_id, ctx::json& event_tmpl, ctx::json& rule, ctx::json& inst_names);
-               std::string generate_fact(std::string item_name, ctx::json& event_tmpl, ctx::json& option, ctx::json& data);
-               std::string generate_modifyinstance(std::string instance_name, ctx::json& cond_tmpl, ctx::json& data);
-
-       }
-
-}      /* namespace ctx */
-
-#endif /* End of __CONTEXT_SCRIPT_GENERATOR_H__ */
index 5209a6ecd7e4a04d1b01ed4e8bb386a61bdda589..c2aaf31afd47ac9041093c4e8d0e9200c529c385 100644 (file)
@@ -289,7 +289,7 @@ void ctx::trigger_timer::on_timer_expired(int hour, int min, int day_of_week)
        result.set(NULL, TIMER_RESPONSE_KEY_DAY_OF_WEEK, convert_day_of_week_to_string(day_of_week));
 
        ctx::json dummy = NULL;
-       trigger->push_fact(TIMER_EVENT_REQ_ID, ERR_NONE, TIMER_EVENT_SUBJECT, dummy, result);
+//     trigger->push_fact(TIMER_EVENT_REQ_ID, ERR_NONE, TIMER_EVENT_SUBJECT, dummy, result);   // TODO deliver event
 }
 
 int ctx::trigger_timer::subscribe(ctx::json option)
index 0c4c53fce05c2a79fe28bf210d4c007881d8969b..1caffe2ecdd7599beb5c6f66c6b5b377d7c3b38b 100644 (file)
@@ -84,29 +84,12 @@ void ctx::context_trigger::process_request(ctx::request_info* request)
        }
 }
 
-// TODO remove
-void ctx::context_trigger::push_fact(int req_id, int error, const char* subject, ctx::json& option, ctx::json& data)
-{
-       context_fact *fact = new(std::nothrow) context_fact(req_id, error, subject, option, data);
-       IF_FAIL_VOID_TAG(fact, _E, "Memory allocation failed");
-
-       process_fact(fact);
-
-}
-
-// TODO: remove
-void ctx::context_trigger::process_fact(ctx::context_fact* fact)
-{
-       // Process the context fact.
-       rule_mgr->on_event_received(fact->get_subject(), fact->get_option(), fact->get_data());
-}
-
 void ctx::context_trigger::process_initialize(ctx::context_manager_impl* mgr)
 {
        rule_mgr = new(std::nothrow) rule_manager();
        IF_FAIL_VOID_TAG(rule_mgr, _E, "Memory allocation failed");
 
-       bool ret = rule_mgr->init(this, mgr);
+       bool ret = rule_mgr->init(mgr);
        if (!ret) {
                _E("Context trigger initialization failed.");
                raise(SIGTERM);
index 28d437362b93f1cceaa2594becfd2a58c6905d6d..0396f1f1c2f4a7462d7ad4092b4360e2e61d0727 100644 (file)
@@ -34,11 +34,9 @@ namespace ctx {
                        void release();
 
                        bool assign_request(ctx::request_info* request);
-                       void push_fact(int req_id, int error, const char* subject, ctx::json& option, ctx::json& data); // TODO remove
 
                private:
                        void process_request(ctx::request_info* request);
-                       void process_fact(ctx::context_fact* fact);
                        void process_initialize(ctx::context_manager_impl* mgr);
 
                        void add_rule(ctx::request_info* request);