From: Somin Kim Date: Thu, 9 Jun 2016 08:45:14 +0000 (+0900) Subject: Re-establish custom provider X-Git-Tag: submit/tizen/20160622.045445^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=634756f89d4b0588885d512524a32dc0ce9ae1f2;p=platform%2Fcore%2Fcontext%2Fcontext-provider.git Re-establish custom provider Change-Id: I58f9f6e99f1d4b881cbcda57bfb80ced85a1147b Signed-off-by: Somin Kim --- diff --git a/include/ProviderList.h b/include/ProviderList.h index 11e54f3..f1dbe3b 100644 --- a/include/ProviderList.h +++ b/include/ProviderList.h @@ -32,7 +32,7 @@ const struct { {SUBJ_APP_STATS, "app-stats"}, {SUBJ_STATE_CALL, "call"}, {SUBJ_STATE_CONTACTS, "contacts"}, - // {SUBJ_CUSTOM, ""}, + {SUBJ_CUSTOM, "custom"}, {SUBJ_STATE_EMAIL, "email"}, {SUBJ_PLACE_GEOFENCE, "geofence"}, {SUBJ_STATE_HEADPHONE, "headphone"}, @@ -93,6 +93,12 @@ const struct { "}", NULL }, + { + SUBJ_CUSTOM, + OPS_SUBSCRIBE, + "{}", + NULL + }, { SUBJ_STATE_EMAIL, OPS_SUBSCRIBE, diff --git a/include/ProviderTypes.h b/include/ProviderTypes.h index 323f505..ed815e3 100644 --- a/include/ProviderTypes.h +++ b/include/ProviderTypes.h @@ -89,6 +89,8 @@ #define SUBJ_PLACE_GEOFENCE "place/geofence" #define SUBJ_PLACE_DETECTION PLACE_DETECTION_SUBJECT +#define SUBJ_CUSTOM "custom" + /* Data & Option Keys */ #define KEY_QUERY_RESULT "QueryResult" #define KEY_RESULT_SIZE "ResultSize" diff --git a/packaging/context-provider.spec b/packaging/context-provider.spec index 97fb3be..4af42f5 100644 --- a/packaging/context-provider.spec +++ b/packaging/context-provider.spec @@ -1,6 +1,6 @@ Name: context-provider Summary: Context Provider -Version: 0.9.0 +Version: 0.9.1 Release: 1 Group: Service/Context License: Apache-2.0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 89bbb83..967c384 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ SET(DEPS ADD_SUBDIRECTORY(shared) ADD_SUBDIRECTORY(activity) ADD_SUBDIRECTORY(app-stats) -#ADD_SUBDIRECTORY(custom) +ADD_SUBDIRECTORY(custom) ADD_SUBDIRECTORY(headphone) ADD_SUBDIRECTORY(system) ADD_SUBDIRECTORY(time) diff --git a/src/custom/CMakeLists.txt b/src/custom/CMakeLists.txt index 4623e2b..4127690 100644 --- a/src/custom/CMakeLists.txt +++ b/src/custom/CMakeLists.txt @@ -1,5 +1,19 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -# prvd_cdef, prvd_deps, and prvd_srcs need to be set properly +SET(target "${target_prefix}-custom") -# Common Profile -FILE(GLOB prvd_srcs ./*.cpp) +#SET(DEPS ${DEPS} +#) + +FILE(GLOB SRCS *.cpp) +#FILE(GLOB SRCS CreateProvider.cpp CustomManager.cpp CustomProvider.cpp) + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(PKG_CUSTOM REQUIRED ${DEPS}) + +FOREACH(flag ${PKG_CUSTOM_CFLAGS}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") +ENDFOREACH(flag) + +ADD_LIBRARY(${target} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${target} ${PKG_CUSTOM_LDFLAGS} ${target_shared}) + +INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/${target_dir}) diff --git a/src/custom/CreateProvider.cpp b/src/custom/CreateProvider.cpp new file mode 100644 index 0000000..3a57524 --- /dev/null +++ b/src/custom/CreateProvider.cpp @@ -0,0 +1,38 @@ +/* + * 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 +#include "CustomManager.h" + +using namespace ctx; + +extern "C" SO_EXPORT ContextProvider* CreateProvider(const char *subject) +{ + static CustomManager *__customMgr = NULL; + + if (!__customMgr) { + __customMgr = new(std::nothrow) CustomManager; + IF_FAIL_RETURN_TAG(__customMgr, NULL, _E, "Memory allocation failed"); + } + + /* Request from client */ + if (STR_EQ(SUBJ_CUSTOM, subject)) { + return __customMgr; + } + + /* Request for each custom provider */ + return __customMgr->getProvider(subject); +} diff --git a/src/custom/CustomBase.cpp b/src/custom/CustomBase.cpp deleted file mode 100644 index 529835b..0000000 --- a/src/custom/CustomBase.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 -#include "CustomBase.h" - -ctx::CustomBase::CustomBase(std::string subject, std::string name, ctx::Json tmpl, std::string owner) : - __subject(subject), - __name(name), - __tmpl(tmpl), - __owner(owner) -{ -} - -ctx::CustomBase::~CustomBase() -{ -} - -bool ctx::CustomBase::isSupported() -{ - return true; -} - -void ctx::CustomBase::submitTriggerItem() -{ - context_manager::registerTriggerItem(__subject.c_str(), OPS_SUBSCRIBE | OPS_READ, - __tmpl.str(), NULL, __owner.c_str()); -} - -void ctx::CustomBase::unsubmitTriggerItem() -{ - context_manager::unregisterTriggerItem(__subject.c_str()); -} - -int ctx::CustomBase::subscribe(const char *subject, ctx::Json option, ctx::Json *requestResult) -{ - return ERR_NONE; - -} - -int ctx::CustomBase::unsubscribe(const char *subject, ctx::Json option) -{ - return ERR_NONE; -} - -int ctx::CustomBase::read(const char *subject, ctx::Json option, ctx::Json *requestResult) -{ - ctx::Json data = __latest.str(); - ctx::context_manager::replyToRead(__subject.c_str(), NULL, ERR_NONE, data); - return ERR_NONE; -} - -int ctx::CustomBase::write(const char *subject, ctx::Json data, ctx::Json *requestResult) -{ - return ERR_NONE; -} - -void ctx::CustomBase::handleUpdate(ctx::Json data) -{ - // Store latest state - __latest = data.str(); - ctx::context_manager::publish(__subject.c_str(), NULL, ERR_NONE, data); -} - -const char* ctx::CustomBase::getSubject() -{ - return __subject.c_str(); -} - -std::string ctx::CustomBase::getOwner() -{ - return __owner; -} - -ctx::Json ctx::CustomBase::getTemplate() -{ - return __tmpl; -} diff --git a/src/custom/CustomBase.h b/src/custom/CustomBase.h deleted file mode 100644 index 13c9d99..0000000 --- a/src/custom/CustomBase.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_CUSTOM_BASE_H_ -#define _CONTEXT_CUSTOM_BASE_H_ - -#include -#include -#include - -namespace ctx { - - class CustomBase : public ContextProvider { - public: - CustomBase(std::string subject, std::string name, ctx::Json tmpl, std::string owner); - ~CustomBase(); - - int subscribe(const char *subject, ctx::Json option, ctx::Json *requestResult); - int unsubscribe(const char *subject, ctx::Json option); - int read(const char *subject, ctx::Json option, ctx::Json *requestResult); - int write(const char *subject, ctx::Json data, ctx::Json *requestResult); - - static bool isSupported(); - void submitTriggerItem(); - void unsubmitTriggerItem(); - - void handleUpdate(ctx::Json data); - - const char* getSubject(); - std::string getOwner(); - ctx::Json getTemplate(); - - private: - std::string __subject; - std::string __name; - ctx::Json __tmpl; - std::string __owner; - ctx::Json __latest; - }; -} - -#endif /* End of _CONTEXT_CUSTOM_BASE_H_ */ diff --git a/src/custom/CustomContextProvider.cpp b/src/custom/CustomContextProvider.cpp deleted file mode 100644 index bcfb7bc..0000000 --- a/src/custom/CustomContextProvider.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include "CustomBase.h" - -static std::map __customMap; -static ctx::DatabaseManager __dbManager; - -static bool __isValidFact(std::string subject, ctx::Json& fact); -static bool __checkValueInt(ctx::Json& tmpl, std::string key, int value); -static bool __checkValueString(ctx::Json& tmpl, std::string key, std::string value); - -void registerProvider(const char *subject, const char *privilege) -{ - ctx::ContextProviderInfo providerInfo(ctx::custom_context_provider::create, - ctx::custom_context_provider::destroy, - const_cast(subject), privilege); - ctx::context_manager::registerProvider(subject, providerInfo); - __customMap[subject]->submitTriggerItem(); -} - -void unregisterProvider(const char* subject) -{ - __customMap[subject]->unsubmitTriggerItem(); - ctx::context_manager::unregisterProvider(subject); -} - -SO_EXPORT ctx::ContextProvider* ctx::custom_context_provider::create(void *data) -{ - // Already created in addItem() function. Return corresponding custom provider - return __customMap[static_cast(data)]; -} - -SO_EXPORT void ctx::custom_context_provider::destroy(void *data) -{ - std::map::iterator it = __customMap.find(static_cast(data)); - if (it != __customMap.end()) { - delete it->second; - __customMap.erase(it); - } -} - -SO_EXPORT bool ctx::initCustomContextProvider() -{ - // Create custom template db - std::string q = std::string("CREATE TABLE IF NOT EXISTS context_trigger_custom_template ") - + "(subject TEXT DEFAULT '' NOT NULL PRIMARY KEY, name TEXT DEFAULT '' NOT NULL, operation INTEGER DEFAULT 3 NOT NULL, " - + "attributes TEXT DEFAULT '' NOT NULL, owner TEXT DEFAULT '' NOT NULL)"; - - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed"); - - // Register custom items - std::string qSelect = "SELECT * FROM context_trigger_custom_template"; - ret = __dbManager.executeSync(qSelect.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates"); - IF_FAIL_RETURN(record.size() > 0, true); - - int error; - std::vector::iterator vedEnd = record.end(); - for (auto vecPos = record.begin(); vecPos != vedEnd; ++vecPos) { - ctx::Json elem = *vecPos; - std::string subject; - std::string name; - std::string attributes; - std::string owner; - elem.get(NULL, "subject", &subject); - elem.get(NULL, "name", &name); - elem.get(NULL, "attributes", &attributes); - elem.get(NULL, "owner", &owner); - - error = ctx::custom_context_provider::addItem(subject, name, ctx::Json(attributes), owner.c_str(), true); - if (error != ERR_NONE) { - _E("Failed to add custom item(%s): %#x", subject.c_str(), error); - } - } - - return true; -} - -SO_EXPORT int ctx::custom_context_provider::addItem(std::string subject, std::string name, ctx::Json tmpl, const char* owner, bool isInit) -{ - std::map::iterator it; - it = __customMap.find(subject); - - if (it != __customMap.end()) { - if ((it->second)->getTemplate() != tmpl) { // Same item name, but different template - return ERR_DATA_EXIST; - } - // Same item name with same template - return ERR_NONE; - } - - // Create custom base - ctx::CustomBase* custom = new(std::nothrow) CustomBase(subject, name, tmpl, owner); - IF_FAIL_RETURN_TAG(custom, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed"); - __customMap[subject] = custom; - - registerProvider(custom->getSubject(), NULL); - - // Add item to custom template db - if (!isInit) { - std::string q = "INSERT OR IGNORE INTO context_trigger_custom_template (subject, name, attributes, owner) VALUES ('" - + subject + "', '" + name + "', '" + tmpl.str() + "', '" + owner + "'); "; - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates"); - } - - return ERR_NONE; -} - -SO_EXPORT int ctx::custom_context_provider::removeItem(std::string subject) -{ - std::map::iterator it; - it = __customMap.find(subject); - IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str()); - - unregisterProvider(subject.c_str()); - - // Remove item from custom template db - std::string q = "DELETE FROM context_trigger_custom_template WHERE subject = '" + subject + "'"; - std::vector record; - bool ret = __dbManager.executeSync(q.c_str(), &record); - IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates"); - - return ERR_NONE; -} - -SO_EXPORT int ctx::custom_context_provider::publishData(std::string subject, ctx::Json fact) -{ - std::map::iterator it; - it = __customMap.find(subject); - IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str()); - - bool ret = __isValidFact(subject, fact); - IF_FAIL_RETURN_TAG(ret, ERR_INVALID_DATA, _E, "Invalid fact(%s)", subject.c_str()); - - __customMap[subject]->handleUpdate(fact); - return ERR_NONE; -} - -bool __isValidFact(std::string subject, ctx::Json& fact) -{ - ctx::Json tmpl = __customMap[subject]->getTemplate(); - IF_FAIL_RETURN_TAG(tmpl != EMPTY_JSON_OBJECT, false, _E, "Failed to get template"); - - bool ret; - std::list keys; - fact.getKeys(&keys); - - for (std::list::iterator it = keys.begin(); it != keys.end(); it++) { - std::string key = *it; - - std::string type; - tmpl.get(key.c_str(), "type", &type); - if (type == "integer") { - int val; - ret = fact.get(NULL, key.c_str(), &val); - IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type"); - - ret = __checkValueInt(tmpl, key, val); - IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value"); - } else if (type == "string") { - std::string val_str; - ret = fact.get(NULL, key.c_str(), &val_str); - IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type"); - - ret = __checkValueString(tmpl, key, val_str); - IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value"); - } else { - _E("Custom fact: invalid data type"); - return false; - } - } - - return true; -} - -bool __checkValueInt(ctx::Json& tmpl, std::string key, int value) -{ - int min, max; - - if (tmpl.get(key.c_str(), "min", &min)) { - IF_FAIL_RETURN(value >= min, false); - } - - if (tmpl.get(key.c_str(), "max", &max)) { - IF_FAIL_RETURN(value <= max, false); - } - - return true; -} - -bool __checkValueString(ctx::Json& tmpl, std::string key, std::string value) -{ - // case1: any value is accepted - if (tmpl.getSize(key.c_str(), "values") <= 0) - return true; - - // case2: check acceptable value - std::string tmplValue; - for (int i = 0; tmpl.getAt(key.c_str(), "values", i, &tmplValue); i++) { - if (tmplValue == value) - return true; - } - - return false; -} - - diff --git a/src/custom/CustomManager.cpp b/src/custom/CustomManager.cpp new file mode 100644 index 0000000..8c01a4b --- /dev/null +++ b/src/custom/CustomManager.cpp @@ -0,0 +1,272 @@ +/* + * 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 +#include +#include +#include "CustomManager.h" +#include "CustomProvider.h" +#include "CustomTypes.h" + +using namespace ctx; + +static std::map __customMap; +static DatabaseManager __dbManager; + +static bool __isValidFact(std::string subject, Json& fact); +static bool __checkValueInt(Json& tmpl, std::string key, int value); +static bool __checkValueString(Json& tmpl, std::string key, std::string value); + +CustomManager::CustomManager() : + BasicProvider(SUBJ_CUSTOM) +{ + __initialize(); +} + +CustomManager::~CustomManager() +{ + /* Custom provider instances will be deleted by Provider Handler */ + __customMap.clear(); +} + +bool CustomManager::isSupported() +{ + return true; +} + +bool CustomManager::unloadable() +{ + return false; +} + +int CustomManager::subscribe() +{ + return ERR_NONE; +} + +int CustomManager::unsubscribe() +{ + return ERR_NONE; +} + +int CustomManager::write(Json data, Json *requestResult) +{ + int error = ERR_NONE; + std::string req; + data.get(NULL, CUSTOM_KEY_REQ, &req); + + std::string packageId; + std::string name; + data.get(NULL, CUSTOM_KEY_PACKAGE_ID, &packageId); + data.get(NULL, CUSTOM_KEY_NAME, &name); + std::string subj = std::string(SUBJ_CUSTOM) + CUSTOM_SEPERATOR + packageId + CUSTOM_SEPERATOR + name; + + if (req == CUSTOM_REQ_TYPE_ADD) { + Json tmpl; + data.get(NULL, CUSTOM_KEY_ATTRIBUTES, &tmpl); + + error = __addCustomItem(subj, name, tmpl, packageId); + } else if (req == CUSTOM_REQ_TYPE_REMOVE) { + error = __removeCustomItem(subj); + if (error == ERR_NONE) { + requestResult->set(NULL, CUSTOM_KEY_SUBJECT, subj); + } + } else if (req == CUSTOM_REQ_TYPE_PUBLISH) { + Json fact; + data.get(NULL, CUSTOM_KEY_FACT, &fact); + + error = __publishData(subj, fact); + } + + return error; +} + +ContextProvider* CustomManager::getProvider(const char* subject) +{ + auto it = __customMap.find(subject); + IF_FAIL_RETURN_TAG(it != __customMap.end(), NULL, _E, "'%s' not found", subject); + + CustomProvider* custom = static_cast(it->second); + return custom; +} + +bool CustomManager::__initialize() +{ + /* Create custom template table */ + std::vector record; + bool ret = __dbManager.executeSync(CUSTOM_TEMPLATE_TABLE_SCHEMA, &record); + IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed"); + + /* Register custom items */ + std::string qSelect = "SELECT * FROM context_trigger_custom_template"; + ret = __dbManager.executeSync(qSelect.c_str(), &record); + IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to query custom templates"); + IF_FAIL_RETURN(record.size() > 0, true); + + int error; + std::vector::iterator vedEnd = record.end(); + for (auto vecPos = record.begin(); vecPos != vedEnd; ++vecPos) { + Json elem = *vecPos; + std::string subject; + std::string name; + std::string attributes; + std::string owner; + elem.get(NULL, CUSTOM_KEY_SUBJECT, &subject); + elem.get(NULL, CUSTOM_KEY_NAME, &name); + elem.get(NULL, CUSTOM_KEY_ATTRIBUTES, &attributes); + elem.get(NULL, CUSTOM_KEY_OWNER, &owner); + + error = __addCustomItem(subject.c_str(), name, Json(attributes), owner, true); + if (error != ERR_NONE) { + _E("Failed to add custom item(%s): %#x", subject.c_str(), error); + } + } + + return true; +} + +int CustomManager::__addCustomItem(std::string subject, std::string name, Json tmpl, std::string owner, bool isInit) +{ + std::map::iterator it; + it = __customMap.find(subject); + + if (it != __customMap.end()) { + if ((it->second)->getTemplate() != tmpl) { /* Same item name, different template */ + return ERR_DATA_EXIST; + } + + return ERR_NONE; /* Same item */ + } + + /* Create custom provider */ + CustomProvider* custom = new(std::nothrow) CustomProvider(subject.c_str(), name, tmpl, owner); + IF_FAIL_RETURN_TAG(custom, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed"); + __customMap[subject] = custom; + + /* Register provider handler & template */ + registerCustomProvider(subject.c_str(), OPS_SUBSCRIBE | OPS_READ, tmpl, NULL, owner.c_str()); + + /* Insert item to custom template db */ + if (!isInit) { + std::string q = "INSERT OR IGNORE INTO context_trigger_custom_template (subject, name, attributes, owner) VALUES ('" + + subject + "', '" + name + "', '" + tmpl.str() + "', '" + owner + "'); "; + std::vector record; + bool ret = __dbManager.executeSync(q.c_str(), &record); + IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query custom templates"); + } + + return ERR_NONE; +} + +int CustomManager::__removeCustomItem(std::string subject) +{ + std::map::iterator it; + it = __customMap.find(subject); + IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str()); + + /* Unregister provider handler & template */ + unregisterCustomProvider(subject.c_str()); + __customMap.erase(it); + + /* Delete item from custom template db */ + std::string q = "DELETE FROM context_trigger_custom_template WHERE subject = '" + subject + "'"; + std::vector record; + bool ret = __dbManager.executeSync(q.c_str(), &record); + IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query custom templates"); + + return ERR_NONE; +} + +int CustomManager::__publishData(std::string subject, Json fact) +{ + std::map::iterator it; + it = __customMap.find(subject); + IF_FAIL_RETURN_TAG(it != __customMap.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str()); + + bool ret = __isValidFact(subject, fact); + IF_FAIL_RETURN_TAG(ret, ERR_INVALID_DATA, _E, "Invalid fact(%s)", subject.c_str()); + + __customMap[subject]->handleUpdate(fact); + return ERR_NONE; +} + +bool __isValidFact(std::string subject, Json& fact) +{ + Json tmpl = __customMap[subject]->getTemplate(); + IF_FAIL_RETURN_TAG(tmpl != EMPTY_JSON_OBJECT, false, _E, "Failed to get template"); + + bool ret; + std::list keys; + fact.getKeys(&keys); + + for (std::list::iterator it = keys.begin(); it != keys.end(); it++) { + std::string key = *it; + + std::string type; + tmpl.get(key.c_str(), "type", &type); + if (type == "integer") { + int val; + ret = fact.get(NULL, key.c_str(), &val); + IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type"); + + ret = __checkValueInt(tmpl, key, val); + IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value"); + } else if (type == "string") { + std::string val_str; + ret = fact.get(NULL, key.c_str(), &val_str); + IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type"); + + ret = __checkValueString(tmpl, key, val_str); + IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value"); + } else { + _E("Custom fact: invalid data type"); + return false; + } + } + + return true; +} + +bool __checkValueInt(Json& tmpl, std::string key, int value) +{ + int min, max; + + if (tmpl.get(key.c_str(), "min", &min)) { + IF_FAIL_RETURN(value >= min, false); + } + + if (tmpl.get(key.c_str(), "max", &max)) { + IF_FAIL_RETURN(value <= max, false); + } + + return true; +} + +bool __checkValueString(Json& tmpl, std::string key, std::string value) +{ + /* case1: any value is accepted */ + if (tmpl.getSize(key.c_str(), "values") <= 0) + return true; + + /* case2: check acceptable value */ + std::string tmplValue; + for (int i = 0; tmpl.getAt(key.c_str(), "values", i, &tmplValue); i++) { + if (tmplValue == value) + return true; + } + + return false; +} diff --git a/src/custom/CustomManager.h b/src/custom/CustomManager.h new file mode 100644 index 0000000..8561cce --- /dev/null +++ b/src/custom/CustomManager.h @@ -0,0 +1,49 @@ +/* + * 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_CUSTOM_MANAGER_H_ +#define _CONTEXT_CUSTOM_MANAGER_H_ + +#include +#include +#include + +namespace ctx { + + class CustomManager : public BasicProvider, CustomRegister { + public: + CustomManager(); + ~CustomManager(); + + int subscribe(); + int unsubscribe(); + int write(Json data, Json *requestResult); + + bool isSupported(); + + bool unloadable(); + + ContextProvider* getProvider(const char* subject); + + private: + bool __initialize(); + int __addCustomItem(std::string subject, std::string name, ctx::Json tmpl, std::string owner, bool isInit = false); + int __removeCustomItem(std::string subject); + int __publishData(std::string, ctx::Json fact); + }; +} + +#endif /* End of _CONTEXT_CUSTOM_MANAGER_H_ */ diff --git a/src/custom/CustomProvider.cpp b/src/custom/CustomProvider.cpp new file mode 100644 index 0000000..53f23c6 --- /dev/null +++ b/src/custom/CustomProvider.cpp @@ -0,0 +1,78 @@ +/* + * 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 "CustomProvider.h" + +using namespace ctx; + +CustomProvider::CustomProvider(const char* subject, std::string name, Json tmpl, std::string owner) : + BasicProvider(subject), + __name(name), + __tmpl(tmpl), + __owner(owner) +{ +} + +CustomProvider::~CustomProvider() +{ +} + +bool CustomProvider::isSupported() +{ + return true; +} + +bool CustomProvider::unloadable() +{ + return false; +} + +int CustomProvider::subscribe() +{ + return ERR_NONE; + +} + +int CustomProvider::unsubscribe() +{ + return ERR_NONE; +} + +int CustomProvider::read() +{ + Json data = __latest.str(); + + replyToRead(NULL, ERR_NONE, data); + return ERR_NONE; +} + +void CustomProvider::handleUpdate(Json data) +{ + /* Store latest state for read request */ + __latest = data.str(); + + publish(NULL, ERR_NONE, data); +} + +std::string CustomProvider::getOwner() +{ + return __owner; +} + +Json CustomProvider::getTemplate() +{ + return __tmpl; +} diff --git a/src/custom/CustomProvider.h b/src/custom/CustomProvider.h new file mode 100644 index 0000000..3def760 --- /dev/null +++ b/src/custom/CustomProvider.h @@ -0,0 +1,51 @@ +/* + * 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_CUSTOM_PROVIDER_H_ +#define _CONTEXT_CUSTOM_PROVIDER_H_ + +#include +#include + +namespace ctx { + + class CustomProvider : public BasicProvider { + public: + CustomProvider(const char* subject, std::string name, ctx::Json tmpl, std::string owner); + ~CustomProvider(); + + int subscribe(); + int unsubscribe(); + int read(); + + bool isSupported(); + + bool unloadable(); + + void handleUpdate(ctx::Json data); + + std::string getOwner(); + ctx::Json getTemplate(); + + private: + std::string __name; + ctx::Json __tmpl; + std::string __owner; + ctx::Json __latest; + }; +} + +#endif /* End of _CONTEXT_CUSTOM_PROVIDER_H_ */ diff --git a/src/custom/CustomTypes.h b/src/custom/CustomTypes.h new file mode 100644 index 0000000..797be6c --- /dev/null +++ b/src/custom/CustomTypes.h @@ -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. + */ + +#ifndef _CONTEXT_CUSTOM_TYPES_H_ +#define _CONTEXT_CUSTOM_TYPES_H_ + +#include + +#define CUSTOM_KEY_REQ "req" +#define CUSTOM_KEY_PACKAGE_ID "packageId" +#define CUSTOM_KEY_NAME "name" +#define CUSTOM_KEY_ATTRIBUTES "attributes" +#define CUSTOM_KEY_FACT "fact" +#define CUSTOM_KEY_SUBJECT "subject" +#define CUSTOM_KEY_OWNER "owner" + +#define CUSTOM_REQ_TYPE_ADD "add" +#define CUSTOM_REQ_TYPE_REMOVE "remove" +#define CUSTOM_REQ_TYPE_PUBLISH "publish" + +#define CUSTOM_SEPERATOR "/" + +#define MEDIA_TABLE_NAME "Log_MediaPlayback" + +#define CUSTOM_TEMPLATE_TABLE_SCHEMA \ + "CREATE TABLE IF NOT EXISTS context_trigger_custom_template " \ + "(subject TEXT DEFAULT '' NOT NULL PRIMARY KEY, name TEXT DEFAULT '' NOT NULL," \ + " operation INTEGER DEFAULT 3 NOT NULL, attributes TEXT DEFAULT '' NOT NULL, " \ + " owner TEXT DEFAULT '' NOT NULL)" + + +#endif /* End of _CONTEXT_CUSTOM_TYPES_H_ */