Convert old style rule to new one 85/90785/4
authorSomin Kim <somin926.kim@samsung.com>
Tue, 4 Oct 2016 08:32:38 +0000 (17:32 +0900)
committerSomin Kim <somin926.kim@samsung.com>
Wed, 12 Oct 2016 10:30:34 +0000 (19:30 +0900)
Change-Id: I5e7d3e74b7b8aaae7011d2d1ca99b638fd46485b
Signed-off-by: Somin Kim <somin926.kim@samsung.com>
src/ComparisonConverter.cpp [new file with mode: 0644]
src/ComparisonConverter.h [new file with mode: 0644]
src/IntComparisonConverter.cpp [new file with mode: 0644]
src/IntComparisonConverter.h [new file with mode: 0644]
src/StringComparisonConverter.cpp [new file with mode: 0644]
src/StringComparisonConverter.h [new file with mode: 0644]
src/TriggerOldRuleTypes.h [new file with mode: 0644]
src/context_trigger.cpp
src/rule_util.cpp [new file with mode: 0644]
src/rule_util.h [new file with mode: 0644]
src/rule_validator.cpp

diff --git a/src/ComparisonConverter.cpp b/src/ComparisonConverter.cpp
new file mode 100644 (file)
index 0000000..ea247e9
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "ComparisonConverter.h"
+
+using namespace ctx;
+
+ComparisonConverter::ComparisonConverter(const char* type, Json& info) :
+       __completed(false),
+       __size(0),
+       __logicalOp(TRIG_RULE_LOGICAL_DISJUNCTION),
+       __type(type),
+       __info(info.str()),
+       __result(EMPTY_JSON_OBJECT)
+{
+       __info.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &__key);
+       __info.get(NULL, OLD_TRIG_RULE_KEY_OPERATOR, &__logicalOp);
+       __size = __info.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR);
+}
+
+int ComparisonConverter::getResult(Json* result)
+{
+       if (__result == EMPTY_JSON_OBJECT)
+               return ERR_INVALID_RULE;
+
+       *result = __result.str();
+
+       return ERR_NONE;
+}
+
+void ComparisonConverter::__convertComparison()
+{
+       IF_FAIL_VOID(!__convertEmptyComparison());
+       IF_FAIL_VOID(!__convertSingleComparison());
+       IF_FAIL_VOID(!__convertMultipleComparison());
+
+       _E("Failed to convert comparison as new format");
+}
+
+bool ComparisonConverter::__convertEmptyComparison()
+{
+       IF_FAIL_RETURN(__size == 0, false);
+
+       Json temp = EMPTY_JSON_OBJECT;
+       __result.set(NULL, __key.c_str(), temp);
+
+       return true;
+}
+
+bool ComparisonConverter::__convertSingleComparison()
+{
+       IF_FAIL_RETURN(__size == 1, false);
+
+       std::string op;
+       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, 0, &op);
+
+       __setConvertedOperator(op);
+       __setComparisonValue();
+
+       return true;
+}
+
+bool ComparisonConverter::__convertMultipleComparison()
+{
+       IF_FAIL_RETURN(__size > 1, false);
+
+       if (__checkOneOf()) {
+               return true;
+       } else if (__checkNoneOf()) {
+               return true;
+       } else if (__checkEtc()) {
+               return true;
+       }
+
+       return false;
+}
+
+bool ComparisonConverter::__checkOneOf()
+{
+       // Or of {==, ...}
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
+       IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_EQUAL_TO), false);
+
+       __setConvertedOperator(TRIG_RULE_OP_ONE_OF);
+       __setComparisonValueArray();
+
+       return true;
+}
+
+bool ComparisonConverter::__checkNoneOf()
+{
+       // And of {!=, ...}
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
+       IF_FAIL_RETURN(__size == __getOperatorCount(TRIG_RULE_OP_NOT_EQUAL_TO), false);
+
+       __setConvertedOperator(TRIG_RULE_OP_NONE_OF);
+       __setComparisonValueArray();
+
+       return true;
+}
+
+bool ComparisonConverter::__checkEtc()
+{
+       return false;
+}
+
+void ComparisonConverter::__setConvertedOperator(std::string op)
+{
+       __result.set(__key.c_str(), TRIG_RULE_KEY_OPERATOR, op);
+}
+
+void ComparisonConverter::__setComparisonValue()
+{
+       std::string valStr;
+       int val;
+
+       if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &valStr)) {
+               __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
+       } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, 0, &val)) {
+               __result.set(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
+       }
+}
+
+void ComparisonConverter::__setComparisonValueArray()
+{
+       std::string valStr;
+       int val;
+       // TODO sort
+       for (int i = 0; i < __size; i++) {
+               if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &valStr)) {
+                       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, valStr);
+               } else if (__info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val)) {
+                       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val);
+               }
+       }
+}
+
diff --git a/src/ComparisonConverter.h b/src/ComparisonConverter.h
new file mode 100644 (file)
index 0000000..54a796f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_COMPARISON_CONVERTER_H_
+#define _CONTEXT_COMPARISON_CONVERTER_H_
+
+#include <Json.h>
+#include "TriggerOldRuleTypes.h"
+
+namespace ctx {
+
+       class ComparisonConverter {
+       public:
+               virtual ~ComparisonConverter() {};
+
+               int getResult(Json* result);
+
+       protected:
+               bool __completed;
+               int __size;
+               std::string __logicalOp;
+               std::string __type;
+               Json __info;
+               Json __result;
+               std::string __key;
+
+               ComparisonConverter(const char* type, Json& info);
+               void __convertComparison();
+               virtual int __getOperatorCount(std::string op) = 0;
+               virtual bool __checkEtc();
+               void __setConvertedOperator(std::string op);
+
+       private:
+               bool __convertEmptyComparison();
+               bool __convertSingleComparison();
+               bool __convertMultipleComparison();
+               bool __checkOneOf();
+               bool __checkNoneOf();
+               void __setComparisonValue();
+               void __setComparisonValueArray();
+       };
+
+}      /* namespace ctx */
+
+#endif /* _CONTEXT_COMPARISON_CONVERTER_H_ */
diff --git a/src/IntComparisonConverter.cpp b/src/IntComparisonConverter.cpp
new file mode 100644 (file)
index 0000000..98aa36d
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <map>
+#include <list>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "IntComparisonConverter.h"
+
+using namespace ctx;
+
+IntComparisonConverter::IntComparisonConverter(Json info) :
+       ComparisonConverter(TRIG_TMPL_TYPE_INTEGER, info)
+{
+       if (__size >= 2) {
+               for (int i = 0; i < __size; i++) {
+                       int val;
+                       std::string op;
+                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_ARR, i, &val);
+                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
+
+                       __insertComparisonInfo(op, val);
+               }
+               __sort();
+       }
+
+       __convertComparison();
+}
+
+void IntComparisonConverter::__insertComparisonInfo(std::string op, int val)
+{
+       IntComparisonMap::iterator it = __map.find(op);
+       if (it == __map.end()) {
+               IntList list;
+               list.push_back(val);
+               __map[op] = list;
+       } else {
+               it->second.push_back(val);
+       }
+}
+
+void IntComparisonConverter::__sort()
+{
+       for (IntComparisonMap::iterator it = __map.begin(); it != __map.end(); it++) {
+               it->second.sort();
+       }
+}
+
+int IntComparisonConverter::__getOperatorCount(std::string op)
+{
+       return __map[op].size();
+}
+
+int IntComparisonConverter::__getMaxValue(std::string op)
+{
+       return __map[op].back();
+}
+
+int IntComparisonConverter::__getMinValue(std::string op)
+{
+       return __map[op].front();
+}
+
+bool IntComparisonConverter::__checkEtc()
+{
+       // Simple version in, notIn
+       IF_FAIL_RETURN(!__checkIn(), true);
+       IF_FAIL_RETURN(!__checkNotIn(), true);
+
+       return false;
+}
+
+
+bool IntComparisonConverter::__checkIn()
+{
+       // And of { >= min, <= max }
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_CONJUNCTION, false);
+       IF_FAIL_RETURN(__size == 2, false);
+       IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO) == 1
+                       && __getOperatorCount(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO) == 1, false);
+
+       int maxOfGE = __getMaxValue(TRIG_RULE_OP_GREATER_THAN_OR_EQUAL_TO);
+       int minOfLE = __getMinValue(TRIG_RULE_OP_LESS_THAN_OR_EQUAL_TO);
+       IF_FAIL_RETURN(maxOfGE <= minOfLE, false);
+
+       __setConvertedOperator(TRIG_RULE_OP_IN);
+       __setComparisonValue(maxOfGE, minOfLE);
+
+       return true;
+}
+
+bool IntComparisonConverter::__checkNotIn()
+{
+       // Or of { < min, > max }
+       IF_FAIL_RETURN(__logicalOp == TRIG_RULE_LOGICAL_DISJUNCTION, false);
+       IF_FAIL_RETURN(__size == 2, false);
+       IF_FAIL_RETURN(__getOperatorCount(TRIG_RULE_OP_GREATER_THAN) == 1
+                       && __getOperatorCount(TRIG_RULE_OP_LESS_THAN) == 1, false);
+
+       int maxOfL = __getMaxValue(TRIG_RULE_OP_LESS_THAN);
+       int minOfG = __getMinValue(TRIG_RULE_OP_GREATER_THAN);
+       IF_FAIL_RETURN(maxOfL <= minOfG, false);
+
+       __setConvertedOperator(TRIG_RULE_OP_NOT_IN);
+       __setComparisonValue(maxOfL, minOfG);
+
+       return true;
+}
+
+void IntComparisonConverter::__setComparisonValue(int val1, int val2)
+{
+       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val1);
+       __result.append(__key.c_str(), TRIG_RULE_KEY_VALUE, val2);
+}
+
diff --git a/src/IntComparisonConverter.h b/src/IntComparisonConverter.h
new file mode 100644 (file)
index 0000000..ec72e6b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_INT_COMPARISON_CONVERTER_H_
+#define _CONTEXT_INT_COMPARISON_CONVERTER_H_
+
+#include <list>
+#include <Json.h>
+#include "ComparisonConverter.h"
+
+namespace ctx {
+
+       class IntComparisonConverter : public ComparisonConverter {
+               typedef std::list<int> IntList;         // Integer value list
+               typedef std::map<std::string, IntList> IntComparisonMap;                // { operator, IntList }
+
+       public:
+               IntComparisonConverter(Json info);
+               ~IntComparisonConverter() {};
+
+       private:
+               IntComparisonMap __map;
+
+               void __insertComparisonInfo(std::string op, int val);
+               void __sort();
+               int __getMaxValue(std::string op);
+               int __getMinValue(std::string op);
+
+               bool __checkIn();
+               bool __checkNotIn();
+               void __setComparisonValue(int val1, int val2);
+               /* From CompariconConverter */
+               int __getOperatorCount(std::string op);
+               bool __checkEtc();
+       };
+
+}      /* namespace ctx */
+
+#endif /* _CONTEXT_INT_COMPARISON_CONVERTER_H_ */
diff --git a/src/StringComparisonConverter.cpp b/src/StringComparisonConverter.cpp
new file mode 100644 (file)
index 0000000..88fd359
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include "StringComparisonConverter.h"
+
+using namespace ctx;
+
+StringComparisonConverter::StringComparisonConverter(Json info) :
+       ComparisonConverter(TRIG_TMPL_TYPE_STRING, info)
+{
+       if (__size >= 2) {
+               for (int i = 0; i < __size; i++) {
+                       std::string op;
+                       __info.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR, i, &op);
+
+                       __map[op]++;
+               }
+       }
+
+       __convertComparison();
+}
+
+
+int StringComparisonConverter::__getOperatorCount(std::string op)
+{
+       return __map[op];
+}
+
diff --git a/src/StringComparisonConverter.h b/src/StringComparisonConverter.h
new file mode 100644 (file)
index 0000000..2f45162
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_STRING_COMPARISON_CONVERTER_H_
+#define _CONTEXT_STRING_COMPARISON_CONVERTER_H_
+
+#include <map>
+#include <Json.h>
+#include "ComparisonConverter.h"
+
+namespace ctx {
+
+       class StringComparisonConverter : public ComparisonConverter {
+               typedef std::map<std::string, int> StringComparisonMap;
+
+       public:
+               StringComparisonConverter(Json info);
+               ~StringComparisonConverter() {};
+
+       private:
+               StringComparisonMap __map;
+
+               /* From CompariconConverter */
+               int __getOperatorCount(std::string op);
+       };
+
+}      /* namespace ctx */
+
+#endif /* _CONTEXT_STRING_COMPARISON_CONVERTER_H_ */
diff --git a/src/TriggerOldRuleTypes.h b/src/TriggerOldRuleTypes.h
new file mode 100644 (file)
index 0000000..fe85d67
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
+#define _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_
+
+/* Old Rule Keys */
+#define OLD_TRIG_RULE_KEY_EVENT "EVENT"
+#define OLD_TRIG_RULE_KEY_EVENT_ITEM "ITEM_NAME"
+#define OLD_TRIG_RULE_KEY_EVENT_OPERATOR "ITEM_OPERATOR"
+#define OLD_TRIG_RULE_KEY_EVENT_OPTION "OPTION"
+#define OLD_TRIG_RULE_KEY_OPERATOR "OPERATOR"
+#define OLD_TRIG_RULE_KEY_CONDITION "CONDITION"
+#define OLD_TRIG_RULE_KEY_CONDITION_ITEM "ITEM_NAME"
+#define OLD_TRIG_RULE_KEY_CONDITION_OPERATOR "ITEM_OPERATOR"
+#define OLD_TRIG_RULE_KEY_CONDITION_OPTION "OPTION"
+#define OLD_TRIG_RULE_KEY_DATA_ARR "DATA_ARR"
+#define OLD_TRIG_RULE_KEY_DATA_KEY "DATA_KEY"
+#define OLD_TRIG_RULE_KEY_DATA_KEY_OPERATOR "DATA_KEY_OPERATOR"
+#define OLD_TRIG_RULE_KEY_DATA_VALUE_ARR "DATA_VALUE_ARR"
+#define OLD_TRIG_RULE_KEY_DATA_VALUE_OPERATOR_ARR "DATA_VALUE_OPER_ARR"
+
+#endif /* _CONTEXT_TRIGGER_OLD_RULE_TYPES_H_ */
index d165575393b61dc9476391a518d5a7034df97bc0..169dbffcf90c87111a91e27df59a8058f8a66f6b 100644 (file)
 
 //#include <sstream>
 //#include <iomanip>
-#include <Types.h>
-#include <DBusTypes.h>
-#include <Json.h>
-#include <DBusClient.h>
 #include <app_control_internal.h>
 #include <bundle.h>
 #include <bundle_internal.h>
-
+#include <pkgmgr-info.h>
 #include <context_trigger.h>
 #include <context_trigger_internal.h>
+#include <Types.h>
+#include <DBusTypes.h>
+#include <Json.h>
+#include <DBusClient.h>
 #include <TriggerTypes.h>
 #include <TriggerRuleTypes.h>
-#include <pkgmgr-info.h>
+#include "TriggerOldRuleTypes.h"
 #include "rule_validator.h"
+#include "rule_util.h"
 
 //#define DOUBLE_PRECISION 2
 #define TYPE_EVENT 1
 #define TYPE_CONDITION 2
 #define TYPE_OPTION TRIG_TMPL_KEY_OPTION
 #define TYPE_ATTRIBUTE TRIG_TMPL_KEY_ATTRIBUTE
-#define OLD_INITIAL_RULE "{ \"" OLD_TRIG_RULE_KEY_DESCRIPTION "\" : \"\", \"" OLD_TRIG_RULE_KEY_DETAILS "\" : {  } }"
 #define OLD_INITIAL_ENTRY "{ \"" OLD_TRIG_RULE_KEY_DATA_ARR "\" : [ ] }"
 #define INITIAL_REF "{ \"" TRIG_TMPL_KEY_OPTION "\" : [ ], \"" TRIG_TMPL_KEY_ATTRIBUTE "\" : [ ] }"
+#define INITIAL_RULE \
+"{ \"" TRIG_RULE_KEY_DESCRIPTION "\" : \"\", \"" TRIG_RULE_KEY_EVENT "\" : { }, \"" TRIG_RULE_KEY_CONDITION "\" : [ ], \"" \
+TRIG_RULE_KEY_ACTION "\" : { }, \"" _TRIG_RULE_KEY_EXTRA "\": { } }"
+#define INITIAL_ENTRY "{ \"" TRIG_RULE_KEY_OPTION "\": { }, \"" TRIG_RULE_KEY_COMPARISON "\" : { } }"
 
 static ctx::DBusClient __dbusClient;
 
@@ -53,11 +57,13 @@ static std::string get_custom_item_subject(const char* provider, const char* ite
 //static std::string double_to_string(int value);
 
 typedef struct _context_trigger_rule_s {
-       ctx::Json jrule;
+       ctx::Json jold_rule;
+       ctx::Json jrule;        // description, event{}, condition[], action{}, _extra{}
        ctx::Json jref;
 
        _context_trigger_rule_s() {
-               jrule = OLD_INITIAL_RULE;
+               jold_rule = EMPTY_JSON_OBJECT;
+               jrule = INITIAL_RULE;
                jref = INITIAL_REF;
        }
 } _context_trigger_rule_h;
@@ -83,23 +89,25 @@ SO_EXPORT int context_trigger_add_rule(context_trigger_rule_h rule, int* rule_id
        ASSERT_NOT_NULL(rule && rule_id);
 
        // Err: No event
-       std::string ename;
-       bool ret = (rule->jrule).get(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_EVENT, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
-       if (!ret)
+       if (!ctx::rule_util::isEventSet(rule->jrule)) {
                return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
 
-       // Err: No action added
-       std::string type;
-       ret = (rule->jrule).get(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_TYPE, &type);
-       if (!ret)
+       // Err: No action
+       if (!ctx::rule_util::isActionSet(rule->jrule)) {
                return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
+       }
+
+       // If condition size isn't greater than 1, update logical operator as default
+       if ((rule->jrule).getSize(NULL, TRIG_RULE_KEY_CONDITION) <= 1) {
+               (rule->jrule).set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, TRIG_RULE_LOGICAL_CONJUNCTION);
+       }
 
        ctx::Json jrule_id;
        int error = __dbusClient.write(SUBJ_TRIGGER_ADD, rule->jrule, &jrule_id);
 
        if (error == ERR_NONE) {
                jrule_id.get(NULL, TRIG_KEY_RULE_ID, rule_id);
-               (rule->jrule).set(NULL, TRIG_KEY_RULE_ID, *rule_id);
        }
 
        return error;
@@ -209,6 +217,7 @@ SO_EXPORT int context_trigger_get_own_rule_ids(int** enabled_rule_ids, int* enab
        return error;
 }
 
+
 SO_EXPORT int context_trigger_get_rule_by_id(int rule_id, context_trigger_rule_h* rule)
 {
        _D("BEGIN");
@@ -245,9 +254,11 @@ SO_EXPORT int context_trigger_rule_create(context_trigger_logical_type_e logical
        if (logical_str.empty()) {
                return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
        }
-       // TODO SOM
+
        *rule = new(std::nothrow) _context_trigger_rule_h();
-       (*rule)->jrule.set(OLD_TRIG_RULE_KEY_DETAILS, OLD_TRIG_RULE_KEY_OPERATOR, logical_str);
+       (*rule)->jold_rule.set(NULL, OLD_TRIG_RULE_KEY_OPERATOR, logical_str);
+
+       (*rule)->jrule.set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, logical_str);
 
        return ERR_NONE;
 }
@@ -268,14 +279,15 @@ SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, contex
        _D("BEGIN");
        ASSERT_NOT_NULL(rule && entry);
 
-       std::string des;
-       bool ret = (rule->jrule).get(NULL, OLD_TRIG_RULE_KEY_DESCRIPTION, &des);
+       // Check if rule handle is created
+       ctx::Json extra;
+       bool ret = (rule->jrule).get(NULL, _TRIG_RULE_KEY_EXTRA, &extra);
        IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER);
 
        if (entry->type == TYPE_EVENT) {
                // Err: More than one event
                ctx::Json elem;
-               if ((rule->jrule).get(OLD_TRIG_RULE_KEY_DETAILS, OLD_TRIG_RULE_KEY_EVENT, &elem)) {
+               if ((rule->jold_rule).get(NULL, OLD_TRIG_RULE_KEY_EVENT, &elem)) {
                        return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
                }
 
@@ -290,7 +302,10 @@ SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, contex
                IF_FAIL_RETURN(ret, CONTEXT_TRIGGER_ERROR_INVALID_RULE);
 
                ctx::Json temp = (entry->jentry).str();
-               ret = (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS, OLD_TRIG_RULE_KEY_EVENT, temp);
+               ret = (rule->jold_rule).set(NULL, OLD_TRIG_RULE_KEY_EVENT, temp);
+
+               int error = ctx::rule_util::setEvent(entry->jentry, &(rule->jrule));
+               IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to add event entry");
        } else if (entry->type == TYPE_CONDITION) {
                // Err: Condition without comparison data
                if ((entry->jentry).getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) < 1) {
@@ -313,7 +328,7 @@ SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, contex
 
                        // If event is already added ....
                        std::string ename;
-                       ret = (rule->jrule).get(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_EVENT, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
+                       ret = (rule->jold_rule).get(OLD_TRIG_RULE_KEY_EVENT, OLD_TRIG_RULE_KEY_EVENT_ITEM, &ename);
                        if (ret) {
                                // Err: Check referential information if exists
                                ret = ctx::rule_validator::check_referential_data(ename, entry->jref);
@@ -332,7 +347,9 @@ SO_EXPORT int context_trigger_rule_add_entry(context_trigger_rule_h rule, contex
                }
 
                ctx::Json temp = (entry->jentry).str();
-               ret = (rule->jrule).append(OLD_TRIG_RULE_KEY_DETAILS, OLD_TRIG_RULE_KEY_CONDITION, temp);
+               ret = (rule->jold_rule).append(NULL, OLD_TRIG_RULE_KEY_CONDITION, temp);
+
+               ctx::rule_util::addCondition(entry->jentry, &(rule->jrule));
        } else {
                // Entry is not created
                return CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER;
@@ -370,8 +387,7 @@ SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h
        }
 
        // Err: if action arleady exists
-       std::string type;
-       if ((rule->jrule).get(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_TYPE, &type)) {
+       if (ctx::rule_util::isActionSet(rule->jrule)) {
                return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
        }
 
@@ -395,9 +411,6 @@ SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h
        }
        pkgmgrinfo_appinfo_destroy_appinfo(app_info);
 
-       // Set action type
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_TYPE, OLD_TRIG_RULE_KEY_ACTION_TYPE_APP_CONTROL);
-
        // Set app control
        bundle* appctl_bundle = NULL;
        error = app_control_to_bundle(app_control, &appctl_bundle);
@@ -409,8 +422,7 @@ SO_EXPORT int context_trigger_rule_set_action_app_control(context_trigger_rule_h
        IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
 
        std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_APP_CONTROL, appctl_str);
-
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_APP_LAUNCH, TRIG_RULE_KEY_APP_LAUNCH_APP_CONTROL, appctl_str);
        bundle_free_encoded_rawdata(&appctl_raw);
 
        return CONTEXT_TRIGGER_ERROR_NONE;
@@ -426,8 +438,7 @@ SO_EXPORT int context_trigger_rule_set_action_notification(context_trigger_rule_
        IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Privilege checking failed (%#x)", error);
 
        // if action arleady exists
-       std::string type;
-       if ((rule->jrule).get(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_TYPE, &type)) {
+       if (ctx::rule_util::isActionSet(rule->jrule)) {
                return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
        }
 
@@ -444,13 +455,12 @@ SO_EXPORT int context_trigger_rule_set_action_notification(context_trigger_rule_
        }
 
        // Set title, content
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_TYPE, OLD_TRIG_RULE_KEY_ACTION_TYPE_NOTIFICATION);
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_NOTI_TITLE, title);
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_NOTI_CONTENT, content);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_TITLE, title);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_CONTENT, content);
 
        // Set icon path
        if (icon_path) {
-               (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_NOTI_ICON_PATH, icon_path);
+               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_ICON_PATH, icon_path);
        }
 
        // Set app control
@@ -465,7 +475,7 @@ SO_EXPORT int context_trigger_rule_set_action_notification(context_trigger_rule_
                IF_FAIL_RETURN_TAG(error == ERR_NONE, CONTEXT_TRIGGER_ERROR_INVALID_PARAMETER, _E, "Bundle encode failed");
 
                std::string appctl_str = reinterpret_cast<const char*>(appctl_raw);
-               (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_APP_CONTROL, appctl_str);
+               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_NOTIFICATION, TRIG_RULE_KEY_NOTI_APP_CONTROL, appctl_str);
 
                bundle_free_encoded_rawdata(&appctl_raw);
        }
@@ -479,22 +489,19 @@ SO_EXPORT int context_trigger_rule_set_action_dbus_call(context_trigger_rule_h r
        ASSERT_NOT_NULL(rule && bus_name && object_path && interface_name && method_name);
 
        /* if action arleady exists */
-       std::string type;
-       if ((rule->jrule).get(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_TYPE, &type))
+       if (ctx::rule_util::isActionSet(rule->jrule)) {
                return CONTEXT_TRIGGER_ERROR_INVALID_RULE;
-
-       /* Set action type */
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_TYPE, OLD_TRIG_RULE_KEY_ACTION_TYPE_DBUS_CALL);
+       }
 
        /* Set basic dbus method call info */
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_DBUS_NAME, bus_name);
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_DBUS_OBJECT, object_path);
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_DBUS_INTERFACE, interface_name);
-       (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_DBUS_METHOD, method_name);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_NAME, bus_name);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_OBJECT, object_path);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_INTERFACE, interface_name);
+       (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_METHOD, method_name);
 
        /* Set the parameters */
        if (param)
-               (rule->jrule).set(OLD_TRIG_RULE_KEY_DETAILS "." OLD_TRIG_RULE_KEY_ACTION, OLD_TRIG_RULE_KEY_ACTION_DBUS_PARAMETER, param);
+               (rule->jrule).set(TRIG_RULE_KEY_ACTION "." TRIG_RULE_KEY_DBUS_CALL, TRIG_RULE_KEY_DBUS_PARAMETER, param);
 
        return CONTEXT_TRIGGER_ERROR_NONE;
 }
@@ -505,7 +512,7 @@ SO_EXPORT int context_trigger_rule_set_description(context_trigger_rule_h rule,
        _D("BEGIN");
        ASSERT_NOT_NULL(rule);
 
-       (rule->jrule).set(NULL, OLD_TRIG_RULE_KEY_DESCRIPTION, description);
+       (rule->jrule).set(NULL, TRIG_RULE_KEY_DESCRIPTION, description);
 
        return CONTEXT_TRIGGER_ERROR_NONE;
 }
@@ -517,7 +524,7 @@ SO_EXPORT int context_trigger_rule_get_description(context_trigger_rule_h rule,
        ASSERT_NOT_NULL(rule && description);
 
        std::string val;
-       (rule->jrule).get(NULL, OLD_TRIG_RULE_KEY_DESCRIPTION, &val);
+       (rule->jrule).get(NULL, TRIG_RULE_KEY_DESCRIPTION, &val);
 
        *description = strdup(val.c_str());
 
@@ -1101,10 +1108,10 @@ std::string convert_logical_type_to_string(context_trigger_logical_type_e logica
        std::string str;
        switch (logical_type) {
        case CONTEXT_TRIGGER_LOGICAL_CONJUNCTION:
-               str = OLD_TRIG_RULE_KEY_LOGICAL_CONJUNCTION;
+               str = TRIG_RULE_LOGICAL_CONJUNCTION;
                break;
        case CONTEXT_TRIGGER_LOGICAL_DISJUNCTION:
-               str = OLD_TRIG_RULE_KEY_LOGICAL_DISJUNCTION;
+               str = TRIG_RULE_LOGICAL_DISJUNCTION;
                break;
        default:
                break;
diff --git a/src/rule_util.cpp b/src/rule_util.cpp
new file mode 100644 (file)
index 0000000..2934968
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <map>
+#include <list>
+#include <context_trigger.h>
+#include <Types.h>
+#include <TriggerTypes.h>
+#include <TriggerRuleTypes.h>
+#include <TimerManager.h>
+#include "rule_validator.h"
+#include "rule_util.h"
+#include "ComparisonConverter.h"
+#include "IntComparisonConverter.h"
+#include "StringComparisonConverter.h"
+
+using namespace ctx;
+
+static bool __handleTimerEvent(Json& event);
+static int __arrangeDayOfWeek(Json& dayInfo);
+
+int ctx::rule_util::setEvent(Json& entry, Json* rule)
+{
+       Json tempEvent;
+       std::string subject;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &subject);
+
+       Json option;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPTION, &option);
+       tempEvent.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
+
+       Json elem;
+       for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+               Json newElem;
+
+               std::string key;
+               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
+
+               std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
+
+               ComparisonConverter* converter = NULL;
+               if (type == TRIG_TMPL_TYPE_INTEGER) {
+                       converter = new(std::nothrow) IntComparisonConverter(elem);
+               } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
+                       converter = new(std::nothrow) StringComparisonConverter(elem);
+               }
+               IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
+               converter->getResult(&newElem);
+
+               Json detail;
+               newElem.get(NULL, key.c_str(), &detail);
+
+               std::string path = subject + "." + TRIG_RULE_KEY_COMPARISON;
+               tempEvent.set(path.c_str(), key.c_str(), detail);
+               delete converter;
+       }
+
+       // Handle Timer Event
+       if (subject.compare(SUBJ_STATE_ALARM) == 0) {
+               IF_FAIL_RETURN(__handleTimerEvent(tempEvent), ERR_INVALID_RULE);
+       }
+
+       rule->set(NULL, TRIG_RULE_KEY_EVENT, tempEvent);
+
+       // Save event entry's logical to extra info (default and)
+       std::string eventOp = TRIG_RULE_LOGICAL_CONJUNCTION;
+       if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
+               entry.get(NULL, OLD_TRIG_RULE_KEY_EVENT_OPERATOR, &eventOp);
+       }
+       rule->set(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, eventOp);
+
+       return ERR_NONE;
+}
+
+int ctx::rule_util::addCondition(Json& entry, Json* rule)
+{
+       Json tempCond;
+       std::string subject;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_ITEM, &subject);
+
+       Json option;
+       entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPTION, &option);
+       tempCond.set(subject.c_str(), TRIG_RULE_KEY_OPTION, option);
+
+       Json elem;
+       for (int i = 0; entry.getAt(NULL, OLD_TRIG_RULE_KEY_DATA_ARR, i, &elem); i++) {
+               Json newElem;
+
+               std::string key;
+               elem.get(NULL, OLD_TRIG_RULE_KEY_DATA_KEY, &key);
+
+               std::string type = ctx::rule_validator::get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, subject, key);
+
+               ComparisonConverter* converter = NULL;
+               if (type == TRIG_TMPL_TYPE_INTEGER) {
+                       converter = new(std::nothrow) IntComparisonConverter(elem);
+               } else if (type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM) {
+                       converter = new(std::nothrow) StringComparisonConverter(elem);
+               }
+               IF_FAIL_RETURN_TAG(converter, ERR_OUT_OF_MEMORY, _E, "Failed to create comparison converter");
+               converter->getResult(&newElem);
+
+               tempCond.set(subject.c_str(), TRIG_RULE_KEY_COMPARISON, newElem);
+               delete converter;
+       }
+
+       rule->append(NULL, TRIG_RULE_KEY_CONDITION, tempCond);
+
+       // Save event entry's logical to extra info (default and)
+       std::string condOp = TRIG_RULE_LOGICAL_CONJUNCTION;
+       if (entry.getSize(NULL, OLD_TRIG_RULE_KEY_DATA_ARR) > 1) {
+               entry.get(NULL, OLD_TRIG_RULE_KEY_CONDITION_OPERATOR, &condOp);
+       }
+       rule->append(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, condOp);
+
+       return ERR_NONE;
+}
+
+bool __handleTimerEvent(Json& event)
+{
+       Json alarmComp;
+       bool ret = event.get(SUBJ_STATE_ALARM, TRIG_RULE_KEY_COMPARISON, &alarmComp);
+       IF_FAIL_RETURN_TAG(ret, false, _E, "Invalid EVENT_TIME event");
+
+       // Day processing
+       Json dayInfo;
+       bool daySpecified = alarmComp.get(NULL, KEY_DAY_OF_WEEK, &dayInfo);
+
+       if (daySpecified) {
+               Json newDayInfo;
+               newDayInfo.set(NULL, TRIG_RULE_KEY_OPERATOR, TRIG_RULE_OP_ONE_OF);
+
+               int dow = __arrangeDayOfWeek(dayInfo);
+               IF_FAIL_RETURN_TAG(dow > 0, false, _E, "Invalid DayOfWeek info for EVENT_TIME");
+
+               for (int i = 0 ; i < DAYS_PER_WEEK; i++) {
+                       int d = 0x01 << i;
+                       if (dow & d) {
+                               std::string day = TimerManager::dowToStr(d);
+                               newDayInfo.append(NULL, TRIG_RULE_KEY_VALUE, day);
+
+                               // Copy details as option
+                               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, day);
+                       }
+               }
+               event.set(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_COMPARISON, KEY_DAY_OF_WEEK, newDayInfo);
+       } else {
+               // If DayOfWeek is not specified, regard it as Mon ~ Sun
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_MON);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_TUE);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_WED);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_THU);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_FRI);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SAT);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_DAY_OF_WEEK, CONTEXT_TRIGGER_SUN);
+       }
+
+       // Time processing
+       Json timeInfo;
+       alarmComp.get(NULL, KEY_TIME_OF_DAY, &timeInfo);
+
+       int time;
+       std::string timeOp;
+       timeInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &timeOp);
+
+       if (timeOp == TRIG_RULE_OP_EQUAL_TO) {
+               timeInfo.get(NULL, TRIG_RULE_KEY_VALUE, &time);
+               event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
+       } else if (timeOp == TRIG_RULE_OP_ONE_OF) {
+               for (int i = 0; timeInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &time); i++) {
+                       event.append(SUBJ_STATE_ALARM "." TRIG_RULE_KEY_OPTION, KEY_TIME_OF_DAY, time);
+               }
+       }
+
+       return true;
+}
+
+int __arrangeDayOfWeek(Json& dayInfo)
+{
+       std::string dayOp;
+       if (!dayInfo.get(NULL, TRIG_RULE_KEY_OPERATOR, &dayOp)) {
+               return TimerManager::dowToInt(DOW_EVERYDAY);
+       }
+
+       int result = 0;
+       if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO || dayOp == TRIG_RULE_OP_NOT_IN) {
+               result = TimerManager::dowToInt(DOW_EVERYDAY);
+       }
+
+       int dow;
+       std::string day;
+       if (dayOp == TRIG_RULE_OP_EQUAL_TO) {
+               dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
+               dow = TimerManager::dowToInt(day);
+               result |= dow;
+       } else if (dayOp == TRIG_RULE_OP_NOT_EQUAL_TO) {
+               dayInfo.get(NULL, TRIG_RULE_KEY_VALUE, &day);
+               dow = TimerManager::dowToInt(day);
+               dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
+               result &= dow;
+       } else if (dayOp == TRIG_RULE_OP_ONE_OF) {
+               for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
+                       dow = TimerManager::dowToInt(day);
+                       result |= dow;
+               }
+       } else if (dayOp == TRIG_RULE_OP_NONE_OF) {
+               for (int i = 0; dayInfo.getAt(NULL, TRIG_RULE_KEY_VALUE, i, &day); i++) {
+                       dow = TimerManager::dowToInt(day);
+                       dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
+                       result &= dow;
+               }
+       }
+
+       _D("Requested day of week (%#x)", result);
+       return result;
+}
+
+bool ctx::rule_util::isEventSet(Json& rule)
+{
+       ctx::Json event;
+       if (rule.get(NULL, TRIG_RULE_KEY_EVENT, &event)) {
+               if (event != EMPTY_JSON_OBJECT) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+bool ctx::rule_util::isActionSet(Json& rule)
+{
+       ctx::Json action;
+       if (rule.get(NULL, TRIG_RULE_KEY_ACTION, &action)) {
+               if (action != EMPTY_JSON_OBJECT) {
+                       return true;
+               }
+       }
+
+       return false;
+}
diff --git a/src/rule_util.h b/src/rule_util.h
new file mode 100644 (file)
index 0000000..e072433
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_RULE_UTIL_H__
+#define __CONTEXT_RULE_UTIL_H__
+
+#include <Json.h>
+
+namespace ctx {
+
+       namespace rule_util {
+
+               int setEvent(Json& entry, Json* rule);
+               int addCondition(Json& entry, Json* rule);
+               bool isEventSet(Json& rule);
+               bool isActionSet(Json& rule);
+
+       }
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_RULE_UTIL_H__ */
index cdbb9eb8a4b6c0b9ae07679da6b45168c2c0617b..c68641b48c2b3fdf3c2e8d02e75217db8eadae55 100644 (file)
 #include <TriggerTypes.h>
 #include <TriggerRuleTypes.h>
 #include "DBusClient.h"
+#include "TriggerOldRuleTypes.h"
 #include "rule_validator.h"
 
-#define RV_KEY_KEY "key"
-#define RV_KEY_REF "ref"
+using namespace ctx;
 
-typedef std::map<std::string, ctx::Json> template_map_t;
+#define RULE_VALIDATOR_COND_NAME "name"
+#define RULE_VALIDATOR_KEY "key"
+#define RULE_VALIDATOR_TYPE "type"
+#define RULE_VALIDATOR_REF "ref"
+
+typedef std::map<std::string, Json> template_map_t;
 template_map_t template_map;   // <name, template>
 
 static int string_to_int(std::string str);
-static bool check_value_int(ctx::Json& tmpl, std::string key, int value);
-static bool check_value_string(ctx::Json& tmpl, std::string key, std::string value);
-static bool check_value_enum(ctx::Json& tmpl, std::string key, std::string value);
-static ctx::Json get_template(std::string name);
-static bool check_template_int(ctx::Json& elem);
-static bool check_template_string(ctx::Json& elem);
-static bool check_template_enum(ctx::Json& elem);
-static std::string get_data_type(ctx::Json& elem, std::string& key);
+static bool check_value_int(Json& tmpl, std::string key, int value);
+static bool check_value_string(Json& tmpl, std::string key, std::string value);
+static bool check_value_enum(Json& tmpl, std::string key, std::string value);
+static Json get_template(std::string name);
+static bool check_template_int(Json& elem);
+static bool check_template_string(Json& elem);
+static bool check_template_enum(Json& elem);
+static std::string get_data_type(Json& elem, std::string& key);
 static bool is_equal_type(std::string& type1, std::string& type2);
 
 int string_to_int(std::string str)
@@ -52,13 +57,13 @@ int string_to_int(std::string str)
        return i;
 }
 
-ctx::Json get_template(std::string name)
+Json get_template(std::string name)
 {
-       ctx::rule_validator::request_template(name);
+       rule_validator::request_template(name);
        return template_map[name];
 }
 
-int ctx::rule_validator::request_template(std::string name, bool mandatory)
+int rule_validator::request_template(std::string name, bool mandatory)
 {
        if (!mandatory) {
                template_map_t::iterator it = template_map.find(name);
@@ -66,12 +71,12 @@ int ctx::rule_validator::request_template(std::string name, bool mandatory)
        }
 
        // Request template
-       ctx::Json request;
+       Json request;
        request.set(NULL, TRIG_TMPL_KEY_SUBJECT, name);
 
        int req_id;
-       ctx::Json tmpl;
-       ctx::DBusClient dbusClient;
+       Json tmpl;
+       DBusClient dbusClient;
        int error = dbusClient.readSync(SUBJ_TRIGGER_GET_TEMPLATE, request, &req_id, &tmpl);
        if (error == ERR_NOT_SUPPORTED) {
                template_map.erase(name);
@@ -85,22 +90,22 @@ int ctx::rule_validator::request_template(std::string name, bool mandatory)
        return ERR_NONE;
 }
 
-void ctx::rule_validator::remove_template(std::string name)
+void rule_validator::remove_template(std::string name)
 {
        template_map.erase(name);
 }
 
 // called by context_trigger_rule_add_entry()
-bool ctx::rule_validator::check_option(ctx::Json& item)
+bool rule_validator::check_option(Json& item)
 {
        std::string name;
        item.get(NULL, OLD_TRIG_RULE_KEY_EVENT_ITEM, &name);
 
-       ctx::Json tmpl = get_template(name);
+       Json tmpl = get_template(name);
        IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
        // No option needed
-       ctx::Json opt_tmpl;
+       Json opt_tmpl;
        tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
 
        std::list<std::string> opt_keys;
@@ -127,12 +132,12 @@ bool ctx::rule_validator::check_option(ctx::Json& item)
 }
 
 // called by context_trigger_rule_entry_add_option_int()
-bool ctx::rule_validator::check_option_int(std::string name, std::string key, int value)
+bool rule_validator::check_option_int(std::string name, std::string key, int value)
 {
-       ctx::Json tmpl = get_template(name);
+       Json tmpl = get_template(name);
        IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
-       ctx::Json opt_tmpl;
+       Json opt_tmpl;
        tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
 
        // Err: Item with no option
@@ -153,12 +158,12 @@ bool ctx::rule_validator::check_option_int(std::string name, std::string key, in
 }
 
 // called by context_trigger_rule_entry_add_option_string()
-bool ctx::rule_validator::check_option_string(std::string name, std::string key, std::string value)
+bool rule_validator::check_option_string(std::string name, std::string key, std::string value)
 {
-       ctx::Json tmpl = get_template(name);
+       Json tmpl = get_template(name);
        IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
-       ctx::Json opt_tmpl;
+       Json opt_tmpl;
        tmpl.get(NULL, TRIG_TMPL_KEY_OPTION, &opt_tmpl);
 
        // Err: ';' for SQL injection
@@ -209,12 +214,12 @@ bool ctx::rule_validator::check_option_string(std::string name, std::string key,
 }
 
 // called by context_trigger_rule_entry_add_comparison_int()
-bool ctx::rule_validator::check_comparison_int(std::string name, std::string key, std::string op, int value)
+bool rule_validator::check_comparison_int(std::string name, std::string key, std::string op, int value)
 {
-       ctx::Json tmpl = get_template(name);
+       Json tmpl = get_template(name);
        IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
-       ctx::Json attr_tmpl;
+       Json attr_tmpl;
        tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
 
        // Err: Invalid attribute key or Invalid value type
@@ -239,12 +244,12 @@ bool ctx::rule_validator::check_comparison_int(std::string name, std::string key
 }
 
 // called by context_trigger_rule_entry_add_comparison_string()
-bool ctx::rule_validator::check_comparison_string(std::string name, std::string key, std::string op, std::string value)
+bool rule_validator::check_comparison_string(std::string name, std::string key, std::string op, std::string value)
 {
-       ctx::Json tmpl = get_template(name);
-       IF_FAIL_RETURN(tmpl != ctx::Json(EMPTY_JSON_OBJECT), false);
+       Json tmpl = get_template(name);
+       IF_FAIL_RETURN(tmpl != Json(EMPTY_JSON_OBJECT), false);
 
-       ctx::Json attr_tmpl;
+       Json attr_tmpl;
        tmpl.get(NULL, TRIG_TMPL_KEY_ATTRIBUTE, &attr_tmpl);
 
        // Err: ';' for SQL injection
@@ -271,20 +276,20 @@ bool ctx::rule_validator::check_comparison_string(std::string name, std::string
        return true;
 }
 
-bool ctx::rule_validator::check_valid_key(std::string type, std::string name, std::string key)
+bool rule_validator::check_valid_key(std::string type, std::string name, std::string key)
 {
-       ctx::Json tmpl = get_template(name);
+       Json tmpl = get_template(name);
        IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
        // Err: Invalid key
-       ctx::Json tmp;
+       Json tmp;
        bool ret = tmpl.get(type.c_str(), key.c_str(), &tmp);
        IF_FAIL_RETURN(ret, false);
 
        return true;
 }
 
-bool check_value_int(ctx::Json& tmpl, std::string key, int value)
+bool check_value_int(Json& tmpl, std::string key, int value)
 {
        int min, max;
 
@@ -299,12 +304,12 @@ bool check_value_int(ctx::Json& tmpl, std::string key, int value)
        return true;
 }
 
-bool check_value_string(ctx::Json& tmpl, std::string key, std::string value)
+bool check_value_string(Json& tmpl, std::string key, std::string value)
 {
        return true;
 }
 
-bool check_value_enum(ctx::Json& tmpl, std::string key, std::string value)
+bool check_value_enum(Json& tmpl, std::string key, std::string value)
 {
        std::string t_val;
        for (int i = 0; tmpl.getAt(key.c_str(), TRIG_TMPL_TYPE_ENUM, i, &t_val); i++) {
@@ -317,22 +322,22 @@ bool check_value_enum(ctx::Json& tmpl, std::string key, std::string value)
 
 // called by context_trigger_rule_entry_add_comparison()
 // called by context_trigger_rule_entry_add_option()
-bool ctx::rule_validator::set_ref_info(std::string type, ctx::Json* jref, std::string name, std::string key, std::string ref_data)
+bool rule_validator::set_ref_info(std::string type, Json* jref, std::string name, std::string key, std::string ref_data)
 {
-       ctx::Json tmpl = get_template(name);
+       Json tmpl = get_template(name);
        IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, false);
 
-       ctx::Json detailed_tmpl;
+       Json detailed_tmpl;
        tmpl.get(NULL, type.c_str(), &detailed_tmpl);
 
        std::string dt = get_data_type(detailed_tmpl, key);
        IF_FAIL_RETURN(dt == TRIG_TMPL_TYPE_INTEGER || dt == TRIG_TMPL_TYPE_STRING || dt == TRIG_TMPL_TYPE_ENUM, false);
 
-       ctx::Json temp;
-       temp.set(NULL, TRIG_CUSTOM_KEY_NAME, name);
-       temp.set(NULL, RV_KEY_KEY, key);
-       temp.set(NULL, TRIG_TMPL_KEY_TYPE, dt);
-       temp.set(NULL, RV_KEY_REF, ref_data);
+       Json temp;
+       temp.set(NULL, RULE_VALIDATOR_COND_NAME, name);
+       temp.set(NULL, RULE_VALIDATOR_KEY, key);
+       temp.set(NULL, RULE_VALIDATOR_TYPE, dt);
+       temp.set(NULL, RULE_VALIDATOR_REF, ref_data);
 
        if (type == TRIG_TMPL_KEY_OPTION) {
                jref->append(NULL, TRIG_TMPL_KEY_OPTION, temp);
@@ -345,7 +350,7 @@ bool ctx::rule_validator::set_ref_info(std::string type, ctx::Json* jref, std::s
        return true;;
 }
 
-std::string get_data_type(ctx::Json& elem, std::string& key)
+std::string get_data_type(Json& elem, std::string& key)
 {
        std::string data_type;
        bool ret = elem.get(key.c_str(), TRIG_TMPL_KEY_TYPE, &data_type);
@@ -360,28 +365,28 @@ std::string get_data_type(ctx::Json& elem, std::string& key)
 }
 
 // called by context_trigger_rule_entry_add_comparison()
-std::string ctx::rule_validator::get_data_type_from_template(std::string type, std::string name, std::string key)
+std::string rule_validator::get_data_type_from_template(std::string type, std::string name, std::string key)
 {
-       ctx::Json tmpl = get_template(name);
+       Json tmpl = get_template(name);
        IF_FAIL_RETURN(tmpl != EMPTY_JSON_OBJECT, "");
 
-       ctx::Json detailed_tmpl;
+       Json detailed_tmpl;
        tmpl.get(NULL, type.c_str(), &detailed_tmpl);
 
        return get_data_type(detailed_tmpl, key);
 }
 
 // called by context_trigger_rule_add_entry()
-bool ctx::rule_validator::check_referential_data(std::string name, ctx::Json& ref_info)
+bool rule_validator::check_referential_data(std::string name, Json& ref_info)
 {
        std::map<std::string, std::string> type_map;
 
-       ctx::Json ref_data;
+       Json ref_data;
        for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_OPTION, i, &ref_data); i++) {
                std::string ref_key;
-               ref_data.get(NULL, RV_KEY_REF, &ref_key);
+               ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
                std::string cond_type;
-               ref_data.get(NULL, TRIG_TMPL_KEY_TYPE, &cond_type);
+               ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
 
                if (type_map.count(ref_key) == 0) {
                        type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
@@ -393,9 +398,9 @@ bool ctx::rule_validator::check_referential_data(std::string name, ctx::Json& re
 
        for (int i = 0; ref_info.getAt(NULL, TRIG_TMPL_KEY_ATTRIBUTE, i, &ref_data); i++) {
                std::string ref_key;
-               ref_data.get(NULL, RV_KEY_REF, &ref_key);
+               ref_data.get(NULL, RULE_VALIDATOR_REF, &ref_key);
                std::string cond_type;
-               ref_data.get(NULL, TRIG_TMPL_KEY_TYPE, &cond_type);
+               ref_data.get(NULL, RULE_VALIDATOR_TYPE, &cond_type);
 
                if (type_map.count(ref_key) == 0) {
                        type_map[ref_key] = get_data_type_from_template(TRIG_TMPL_KEY_ATTRIBUTE, name, ref_key); // "", if invalid key
@@ -422,7 +427,7 @@ bool is_equal_type(std::string& type1, std::string& type2)
        return false;
 }
 
-bool ctx::rule_validator::is_valid_operator(std::string type, std::string op)
+bool rule_validator::is_valid_operator(std::string type, std::string op)
 {
        if (op == CONTEXT_TRIGGER_EQUAL_TO || op == CONTEXT_TRIGGER_NOT_EQUAL_TO) {
                return true;
@@ -439,7 +444,7 @@ bool ctx::rule_validator::is_valid_operator(std::string type, std::string op)
 }
 
 // For custom item template
-bool ctx::rule_validator::is_valid_template(ctx::Json& attr_template)
+bool rule_validator::is_valid_template(Json& attr_template)
 {
        IF_FAIL_RETURN_TAG(attr_template != EMPTY_JSON_OBJECT, false, _E, "Custom template: empty Json");
 
@@ -454,7 +459,7 @@ bool ctx::rule_validator::is_valid_template(ctx::Json& attr_template)
                IF_FAIL_RETURN_TAG(type == TRIG_TMPL_TYPE_INTEGER || type == TRIG_TMPL_TYPE_STRING || type == TRIG_TMPL_TYPE_ENUM,
                        false, _E, "Custom template: invalid data type");
 
-               ctx::Json elem;
+               Json elem;
                attr_template.get(NULL, key.c_str(), &elem);
                if (type == TRIG_TMPL_TYPE_INTEGER) {
                        ret = check_template_int(elem);
@@ -471,7 +476,7 @@ bool ctx::rule_validator::is_valid_template(ctx::Json& attr_template)
        return true;
 }
 
-bool check_template_int(ctx::Json& elem)
+bool check_template_int(Json& elem)
 {
        std::list<std::string> elem_keys;
        elem.getKeys(&elem_keys);
@@ -501,21 +506,20 @@ bool check_template_int(ctx::Json& elem)
        return true;
 }
 
-bool check_template_string(ctx::Json& elem)
+bool check_template_string(Json& elem)
 {
        std::list<std::string> elem_keys;
        elem.getKeys(&elem_keys);
 
        for (std::list<std::string>::iterator it2 = elem_keys.begin(); it2 != elem_keys.end(); it2++) {
                std::string elem_key = *it2;
-               _D("SOM TEST >>> elem key (%s)", elem_key.c_str());
                IF_FAIL_RETURN_TAG(elem_key == TRIG_TMPL_KEY_TYPE, false, _E, "Custom template: invalid key");
        }
 
        return true;
 }
 
-bool check_template_enum(ctx::Json& elem)
+bool check_template_enum(Json& elem)
 {
        std::list<std::string> elem_keys;
        elem.getKeys(&elem_keys);