Split context_manager into context_manager & context_provider_handler 81/49981/1 accepted/tizen/mobile/20151222.224946 accepted/tizen/tv/20151222.224959 accepted/tizen/wearable/20151222.225032 submit/tizen/20151222.122953 submit/tizen_common/20151229.142028 submit/tizen_common/20151229.144031 submit/tizen_common/20151229.154718
authorMu-Woong <muwoong.lee@samsung.com>
Wed, 21 Oct 2015 12:14:58 +0000 (21:14 +0900)
committerMu-Woong <muwoong.lee@samsung.com>
Wed, 21 Oct 2015 12:14:58 +0000 (21:14 +0900)
Change-Id: Id8c63bfc4bd5739e09faaf84d48fed7d3666e020
Signed-off-by: Mu-Woong <muwoong.lee@samsung.com>
packaging/context-service.spec
src/context_mgr_impl.cpp
src/context_mgr_impl.h
src/provider.cpp [new file with mode: 0644]
src/provider.h [new file with mode: 0644]

index e94a404630b58697738368a9ba5f9c9fd8a1c869..0a9341cb8784e4521846157cddf37a3a9bf01a1f 100644 (file)
@@ -55,14 +55,14 @@ Context-Service
 MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 
 export   CFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default"
-export CXXFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default -Wnon-virtual-dtor -Wno-c++0x-compat"
+export CXXFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default -Wnon-virtual-dtor"
 
 export   CFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
 export CXXFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
 
 export   CFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow -fno-common"
 export CXXFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow"
-#export CXXFLAGS+=" -std=c++0x"
+export CXXFLAGS+=" -std=c++11 -Wno-c++11-compat"
 
 export   CFLAGS+=" -DTIZEN_ENGINEER_MODE"
 export CXXFLAGS+=" -DTIZEN_ENGINEER_MODE"
index b2257ccb0cceb4941685f1234669f264c05eb259..d48d837e4fcd865fd239b1839f00c54cddc36218 100644 (file)
  */
 
 #include <glib.h>
-#include <string>
 #include <list>
 
 #include <types_internal.h>
 #include <json.h>
 #include <provider_iface.h>
 #include "server.h"
-#include "context_mgr_impl.h"
 #include "access_control/privilege.h"
+#include "request.h"
+#include "provider.h"
+#include "context_mgr_impl.h"
 
 /* Context Providers */
 #include <internal/device_context_provider.h>
@@ -68,32 +69,32 @@ bool ctx::context_manager_impl::init()
 
 void ctx::context_manager_impl::release()
 {
-       for (provider_map_t::iterator it = provider_map.begin(); it != provider_map.end(); ++it) {
-               it->second.destroy(it->second.data);
-       }
-       provider_map.clear();
-
-       for (request_list_t::iterator it = subscribe_request_list.begin(); it != subscribe_request_list.end(); ++it) {
-               delete *it;
+       for (auto it = provider_handle_map.begin(); it != provider_handle_map.end(); ++it) {
+               delete it->second;
        }
-       subscribe_request_list.clear();
-
-       for (request_list_t::iterator it = read_request_list.begin(); it != read_request_list.end(); ++it) {
-               delete *it;
-       }
-       read_request_list.clear();
+       provider_handle_map.clear();
 }
 
 bool ctx::context_manager_impl::register_provider(const char *subject, ctx::context_provider_info &provider_info)
 {
-       if (provider_map.find(subject) != provider_map.end()) {
+       if (provider_handle_map.find(subject) != provider_handle_map.end()) {
                _E("The provider for the subject '%s' is already registered.", subject);
                return false;
        }
 
        _SI("Subj: %s, Priv: %s", subject, provider_info.privilege);
-       provider_map[subject] = provider_info;
+       provider_handle_map[subject] = NULL;
+
+       auto it = provider_handle_map.find(subject);
+       context_provider_handler *handle = new(std::nothrow) context_provider_handler(it->first.c_str(), provider_info);
+
+       if (!handle) {
+               _E("Memory allocation failed");
+               provider_handle_map.erase(it);
+               return false;
+       }
 
+       it->second = handle;
        return true;
 }
 
@@ -121,22 +122,38 @@ bool ctx::context_manager_impl::pop_trigger_item(std::string &subject, int &oper
 
 void ctx::context_manager_impl::assign_request(ctx::request_info* request)
 {
+       auto it = provider_handle_map.find(request->get_subject());
+       if (it == provider_handle_map.end()) {
+               _W("Unsupported subject");
+               request->reply(ERR_NOT_SUPPORTED);
+               delete request;
+               return;
+       }
+
+       if (!it->second->is_allowed(request->get_credentials())) {
+               _W("Permission denied");
+               request->reply(ERR_PERMISSION_DENIED);
+               delete request;
+               return;
+       }
+
        switch (request->get_type()) {
        case REQ_SUBSCRIBE:
-               subscribe(request);
+               it->second->subscribe(request);
                break;
        case REQ_UNSUBSCRIBE:
-               unsubscribe(request);
+               it->second->unsubscribe(request);
                break;
        case REQ_READ:
        case REQ_READ_SYNC:
-               read(request);
+               it->second->read(request);
                break;
        case REQ_WRITE:
-               write(request);
+               it->second->write(request);
                break;
        case REQ_SUPPORT:
-               is_supported(request);
+               request->reply(ERR_NONE);
+               delete request;
                break;
        default:
                _E("Invalid type of request");
@@ -146,225 +163,39 @@ void ctx::context_manager_impl::assign_request(ctx::request_info* request)
 
 bool ctx::context_manager_impl::is_supported(const char *subject)
 {
-       provider_map_t::iterator it = provider_map.find(subject);
-       return (it != provider_map.end());
-}
-
-void ctx::context_manager_impl::is_supported(request_info *request)
-{
-       if (is_supported(request->get_subject()))
-               request->reply(ERR_NONE);
-       else
-               request->reply(ERR_NOT_SUPPORTED);
-
-       delete request;
+       auto it = provider_handle_map.find(subject);
+       return (it != provider_handle_map.end());
 }
 
 bool ctx::context_manager_impl::is_allowed(const ctx::credentials *creds, const char *subject)
 {
        IF_FAIL_RETURN(creds, true);    /* In case internal requests */
-       provider_map_t::iterator it = provider_map.find(subject);
-       IF_FAIL_RETURN(it != provider_map.end(), false);
-       IF_FAIL_RETURN(ctx::privilege_manager::is_allowed(creds, it->second.privilege), false);
-       return true;
+       auto it = provider_handle_map.find(subject);
+       IF_FAIL_RETURN(it != provider_handle_map.end(), false);
+       return it->second->is_allowed(creds);
 }
 
-ctx::context_manager_impl::request_list_t::iterator
-ctx::context_manager_impl::find_request(request_list_t& r_list, std::string subject, json& option)
+void ctx::context_manager_impl::_publish(const char* subject, ctx::json &option, int error, ctx::json &data_updated)
 {
-       return find_request(r_list.begin(), r_list.end(), subject, option);
-}
-
-ctx::context_manager_impl::request_list_t::iterator
-ctx::context_manager_impl::find_request(request_list_t& r_list, std::string client, int req_id)
-{
-       request_list_t::iterator it;
-       for (it = r_list.begin(); it != r_list.end(); ++it) {
-               if (client == (*it)->get_client() && req_id == (*it)->get_id()) {
-                       break;
-               }
-       }
-       return it;
-}
-
-ctx::context_manager_impl::request_list_t::iterator
-ctx::context_manager_impl::find_request(request_list_t::iterator begin, request_list_t::iterator end, std::string subject, json& option)
-{
-       //TODO: Do we need to consider the case that the inparam option is a subset of the request description?
-       request_list_t::iterator it;
-       for (it = begin; it != end; ++it) {
-               if (subject == (*it)->get_subject() && option == (*it)->get_description()) {
-                       break;
-               }
-       }
-       return it;
-}
-
-ctx::context_provider_iface *ctx::context_manager_impl::get_provider(ctx::request_info *request)
-{
-       provider_map_t::iterator it = provider_map.find(request->get_subject());
-
-       if (it == provider_map.end()) {
-               _W("Unsupported subject");
-               request->reply(ERR_NOT_SUPPORTED);
-               delete request;
-               return NULL;
-       }
-
-       if (!ctx::privilege_manager::is_allowed(request->get_credentials(), it->second.privilege)) {
-               _W("Permission denied");
-               request->reply(ERR_PERMISSION_DENIED);
-               delete request;
-               return NULL;
-       }
-
-       return it->second.create(it->second.data);
-}
-
-void ctx::context_manager_impl::subscribe(ctx::request_info *request)
-{
-       _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->get_client(), request->get_subject(), request->get_id());
-
-       context_provider_iface *provider = get_provider(request);
-       IF_FAIL_VOID(provider);
-
-       ctx::json request_result;
-       int error = provider->subscribe(request->get_subject(), request->get_description().str(), &request_result);
-
-       _D("Analyzer returned %d", error);
-
-       if (!request->reply(error, request_result) || error != ERR_NONE) {
-               delete request;
-               return;
-       }
-
-       subscribe_request_list.push_back(request);
-}
-
-void ctx::context_manager_impl::unsubscribe(ctx::request_info *request)
-{
-       _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->get_client(), request->get_subject(), request->get_id());
-
-       // Search the subscribe request to be removed
-       request_list_t::iterator target = find_request(subscribe_request_list, request->get_client(), request->get_id());
-       if (target == subscribe_request_list.end()) {
-               _W("Unknown request");
-               delete request;
-               return;
-       }
-
-       // Keep the pointer to the request found
-       request_info *req_found = *target;
-
-       // Remove the request from the list
-       subscribe_request_list.erase(target);
-
-       // Check if there exist the same requests
-       if (find_request(subscribe_request_list, req_found->get_subject(), req_found->get_description()) != subscribe_request_list.end()) {
-               // Do not stop detecting the subject
-               _D("A same request from '%s' exists", req_found->get_client());
-               request->reply(ERR_NONE);
-               delete request;
-               delete req_found;
-               return;
-       }
-
-       // Find the proper provider
-       provider_map_t::iterator ca = provider_map.find(req_found->get_subject());
-       if (ca == provider_map.end()) {
-               _E("Invalid subject '%s'", req_found->get_subject());
-               delete request;
-               delete req_found;
-               return;
-       }
-
-       // Stop detecting the subject
-       int error = ca->second.create(ca->second.data)->unsubscribe(req_found->get_subject(), req_found->get_description());
-       request->reply(error);
-       delete request;
-       delete req_found;
-}
-
-void ctx::context_manager_impl::read(ctx::request_info *request)
-{
-       _I(CYAN("'%s' reads '%s' (RID-%d)"), request->get_client(), request->get_subject(), request->get_id());
-
-       context_provider_iface *provider = get_provider(request);
-       IF_FAIL_VOID(provider);
-
-       ctx::json request_result;
-       int error = provider->read(request->get_subject(), request->get_description().str(), &request_result);
-
-       _D("Analyzer returned %d", error);
-
-       if (!request->reply(error, request_result) || error != ERR_NONE) {
-               delete request;
-               return;
-       }
-
-       read_request_list.push_back(request);
-}
-
-void ctx::context_manager_impl::write(ctx::request_info *request)
-{
-       _I(CYAN("'%s' writes '%s' (RID-%d)"), request->get_client(), request->get_subject(), request->get_id());
-
-       context_provider_iface *provider = get_provider(request);
-       IF_FAIL_VOID(provider);
-
-       ctx::json request_result;
-       int error = provider->write(request->get_subject(), request->get_description(), &request_result);
-
-       _D("Analyzer returned %d", error);
-
-       request->reply(error, request_result);
-       delete request;
-}
-
-bool ctx::context_manager_impl::_publish(const char* subject, ctx::json option, int error, ctx::json data_updated)
-{
-       IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter");
-
        _I("Publishing '%s'", subject);
        _J("Option", option);
 
-       request_list_t::iterator end = subscribe_request_list.end();
-       request_list_t::iterator target = find_request(subscribe_request_list.begin(), end, subject, option);
+       auto it = provider_handle_map.find(subject);
+       IF_FAIL_VOID(it != provider_handle_map.end());
 
-       while (target != end) {
-               if (!(*target)->publish(error, data_updated)) {
-                       return false;
-               }
-               target = find_request(++target, end, subject, option);
-       }
-
-       return true;
+       it->second->publish(option, error, data_updated);
 }
 
-bool ctx::context_manager_impl::_reply_to_read(const char* subject, ctx::json option, int error, ctx::json data_read)
+void ctx::context_manager_impl::_reply_to_read(const char* subject, ctx::json &option, int error, ctx::json &data_read)
 {
-       IF_FAIL_RETURN_TAG(subject, false, _E, "Invalid parameter");
-
        _I("Sending data of '%s'", subject);
        _J("Option", option);
        _J("Data", data_read);
 
-       request_list_t::iterator end = read_request_list.end();
-       request_list_t::iterator target = find_request(read_request_list.begin(), end, subject, option);
-       request_list_t::iterator prev;
-
-       ctx::json dummy;
+       auto it = provider_handle_map.find(subject);
+       IF_FAIL_VOID(it != provider_handle_map.end());
 
-       while (target != end) {
-               (*target)->reply(error, dummy, data_read);
-               prev = target;
-               target = find_request(++target, end, subject, option);
-
-               delete *prev;
-               read_request_list.erase(prev);
-       }
-
-       return true;
+       it->second->reply_to_read(option, error, data_read);
 }
 
 struct published_data_s {
@@ -387,14 +218,14 @@ gboolean ctx::context_manager_impl::thread_switcher(gpointer data)
        published_data_s *tuple = static_cast<published_data_s*>(data);
 
        switch (tuple->type) {
-               case REQ_SUBSCRIBE:
-                       tuple->mgr->_publish(tuple->subject.c_str(), tuple->option, tuple->error, tuple->data);
-                       break;
-               case REQ_READ:
-                       tuple->mgr->_reply_to_read(tuple->subject.c_str(), tuple->option, tuple->error, tuple->data);
-                       break;
-               default:
-                       _W("Invalid type");
+       case REQ_SUBSCRIBE:
+               tuple->mgr->_publish(tuple->subject.c_str(), tuple->option, tuple->error, tuple->data);
+               break;
+       case REQ_READ:
+               tuple->mgr->_reply_to_read(tuple->subject.c_str(), tuple->option, tuple->error, tuple->data);
+               break;
+       default:
+               _W("Invalid type");
        }
 
        delete tuple;
index 3e35e02da728d848dbffd36b56975bbf9c905590..f8847610e1cf2778aa3ddbf72cee889057dffcd0 100644 (file)
 #ifndef __CONTEXT_MANAGER_IMPL_H__
 #define __CONTEXT_MANAGER_IMPL_H__
 
-#include <vector>
-#include <list>
+#include <string>
 #include <map>
 #include <context_mgr.h>
 #include <context_mgr_iface.h>
-#include "request.h"
 
 namespace ctx {
 
        /* Forward declaration */
        class credentials;
+       class request_info;
+       class context_provider_handler;
 
        class context_manager_impl : public context_manager_iface {
        public:
-               typedef std::list<request_info*> request_list_t;
-
                context_manager_impl();
                ~context_manager_impl();
 
@@ -51,27 +49,11 @@ namespace ctx {
                bool reply_to_read(const char *subject, ctx::json &option, int error, ctx::json &data_read);
 
        private:
-               typedef std::map<std::string, context_provider_info> provider_map_t;
-
-               request_list_t subscribe_request_list;
-               request_list_t read_request_list;
-               provider_map_t provider_map;
-
-               void subscribe(request_info *request);
-               void unsubscribe(request_info *request);
-               void read(request_info *request);
-               void write(request_info *request);
-               void is_supported(request_info *request);
-
-               context_provider_iface *get_provider(request_info *request);
+               std::map<std::string, context_provider_handler*> provider_handle_map;
 
                static gboolean thread_switcher(gpointer data);
-               bool _publish(const char *subject, ctx::json option, int error, ctx::json data_updated);
-               bool _reply_to_read(const char *subject, ctx::json option, int error, ctx::json data_read);
-
-               request_list_t::iterator find_request(request_list_t& r_list, std::string subject, json& option);
-               request_list_t::iterator find_request(request_list_t& r_list, std::string client, int req_id);
-               request_list_t::iterator find_request(request_list_t::iterator begin, request_list_t::iterator end, std::string subject, json& option);
+               void _publish(const char *subject, ctx::json &option, int error, ctx::json &data_updated);
+               void _reply_to_read(const char *subject, ctx::json &option, int error, ctx::json &data_read);
 
        };      /* class context_manager_impl */
 
diff --git a/src/provider.cpp b/src/provider.cpp
new file mode 100644 (file)
index 0000000..582c823
--- /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 <glib.h>
+#include <types_internal.h>
+#include <json.h>
+#include "access_control/privilege.h"
+#include "server.h"
+#include "request.h"
+#include "provider.h"
+
+ctx::context_provider_handler::context_provider_handler(const char *subj, ctx::context_provider_info &prvd) :
+       subject(subj),
+       provider_info(prvd)
+{
+}
+
+ctx::context_provider_handler::~context_provider_handler()
+{
+       for (auto it = subscribe_requests.begin(); it != subscribe_requests.end(); ++it) {
+               delete *it;
+       }
+       subscribe_requests.clear();
+
+       for (auto it = read_requests.begin(); it != read_requests.end(); ++it) {
+               delete *it;
+       }
+       read_requests.clear();
+
+       provider_info.destroy(provider_info.data);
+}
+
+bool ctx::context_provider_handler::is_allowed(const ctx::credentials *creds)
+{
+       IF_FAIL_RETURN(creds, true);    /* In case of internal requests */
+       return privilege_manager::is_allowed(creds, provider_info.privilege);
+}
+
+ctx::context_provider_iface* ctx::context_provider_handler::get_provider(ctx::request_info *request)
+{
+       context_provider_iface *provider = provider_info.create(provider_info.data);
+       if (!provider) {
+               _E("Memory allocation failed");
+               delete request;
+               return NULL;
+       }
+
+       return provider;
+}
+
+void ctx::context_provider_handler::subscribe(ctx::request_info *request)
+{
+       _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+
+       context_provider_iface *provider = get_provider(request);
+       IF_FAIL_VOID(provider);
+
+       ctx::json request_result;
+       int error = provider->subscribe(subject, request->get_description().str(), &request_result);
+
+       if (!request->reply(error, request_result) || error != ERR_NONE) {
+               delete request;
+               return;
+       }
+
+       subscribe_requests.push_back(request);
+}
+
+void ctx::context_provider_handler::unsubscribe(ctx::request_info *request)
+{
+       _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+
+       // Search the subscribe request to be removed
+       auto target = find_request(subscribe_requests, request->get_client(), request->get_id());
+       if (target == subscribe_requests.end()) {
+               _W("Unknown request");
+               delete request;
+               return;
+       }
+
+       // Keep the pointer to the request found
+       request_info *req_found = *target;
+
+       // Remove the request from the list
+       subscribe_requests.erase(target);
+
+       // Check if there exist the same requests
+       if (find_request(subscribe_requests, req_found->get_description()) != subscribe_requests.end()) {
+               // Do not stop detecting the subject
+               _D("A same request from '%s' exists", req_found->get_client());
+               request->reply(ERR_NONE);
+               delete request;
+               delete req_found;
+               return;
+       }
+
+       // Get the provider
+       context_provider_iface *provider = get_provider(request);
+       IF_FAIL_VOID(provider);
+
+       // Stop detecting the subject
+       int error = provider->unsubscribe(subject, req_found->get_description());
+       request->reply(error);
+       delete request;
+       delete req_found;
+}
+
+void ctx::context_provider_handler::read(ctx::request_info *request)
+{
+       _I(CYAN("'%s' reads '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+
+       context_provider_iface *provider = get_provider(request);
+       IF_FAIL_VOID(provider);
+
+       ctx::json request_result;
+       int error = provider->read(subject, request->get_description().str(), &request_result);
+
+       if (!request->reply(error, request_result) || error != ERR_NONE) {
+               delete request;
+               return;
+       }
+
+       read_requests.push_back(request);
+}
+
+void ctx::context_provider_handler::write(ctx::request_info *request)
+{
+       _I(CYAN("'%s' writes '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+
+       context_provider_iface *provider = get_provider(request);
+       IF_FAIL_VOID(provider);
+
+       ctx::json request_result;
+       int error = provider->write(subject, request->get_description(), &request_result);
+
+       request->reply(error, request_result);
+       delete request;
+}
+
+bool ctx::context_provider_handler::publish(ctx::json &option, int error, ctx::json &data_updated)
+{
+       auto end = subscribe_requests.end();
+       auto target = find_request(subscribe_requests.begin(), end, option);
+
+       while (target != end) {
+               if (!(*target)->publish(error, data_updated)) {
+                       return false;
+               }
+               target = find_request(++target, end, option);
+       }
+
+       return true;
+}
+
+bool ctx::context_provider_handler::reply_to_read(ctx::json &option, int error, ctx::json &data_read)
+{
+       auto end = read_requests.end();
+       auto target = find_request(read_requests.begin(), end, option);
+       auto prev = target;
+
+       ctx::json dummy;
+
+       while (target != end) {
+               (*target)->reply(error, dummy, data_read);
+               prev = target;
+               target = find_request(++target, end, option);
+
+               delete *prev;
+               read_requests.erase(prev);
+       }
+
+       return true;
+}
+
+ctx::context_provider_handler::request_list_t::iterator
+ctx::context_provider_handler::find_request(request_list_t &r_list, json &option)
+{
+       return find_request(r_list.begin(), r_list.end(), option);
+}
+
+ctx::context_provider_handler::request_list_t::iterator
+ctx::context_provider_handler::find_request(request_list_t &r_list, std::string client, int req_id)
+{
+       for (auto it = r_list.begin(); it != r_list.end(); ++it) {
+               if (client == (*it)->get_client() && req_id == (*it)->get_id()) {
+                       return it;
+               }
+       }
+       return r_list.end();
+}
+
+ctx::context_provider_handler::request_list_t::iterator
+ctx::context_provider_handler::find_request(request_list_t::iterator begin, request_list_t::iterator end, json &option)
+{
+       for (auto it = begin; it != end; ++it) {
+               if (option == (*it)->get_description()) {
+                       return it;
+               }
+       }
+       return end;
+}
diff --git a/src/provider.h b/src/provider.h
new file mode 100644 (file)
index 0000000..c7dbfd0
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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_PROVIDER_HANDLER_H__
+#define __CONTEXT_PROVIDER_HANDLER_H__
+
+#include <string>
+#include <list>
+#include <provider_iface.h>
+
+namespace ctx {
+
+       class json;
+       class credentials;
+       class request_info;
+
+       class context_provider_handler {
+       public:
+               typedef std::list<request_info*> request_list_t;
+
+               context_provider_handler(const char *subj, context_provider_info &prvd);
+               ~context_provider_handler();
+
+               bool is_allowed(const credentials *creds);
+
+               void subscribe(request_info *request);
+               void unsubscribe(request_info *request);
+               void read(request_info *request);
+               void write(request_info *request);
+
+               bool publish(ctx::json &option, int error, ctx::json &data_updated);
+               bool reply_to_read(ctx::json &option, int error, ctx::json &data_read);
+
+       private:
+               const char *subject;
+               context_provider_info provider_info;
+               request_list_t subscribe_requests;
+               request_list_t read_requests;
+
+               context_provider_iface* get_provider(request_info *request);
+               request_list_t::iterator find_request(request_list_t &r_list, json &option);
+               request_list_t::iterator find_request(request_list_t &r_list, std::string client, int req_id);
+               request_list_t::iterator find_request(request_list_t::iterator begin, request_list_t::iterator end, json &option);
+
+       };      /* class context_provider_handler */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_PROVIDER_HANDLER_H__ */