| 1 | /************************************************************************* |
| 2 | * libjson-rpc-cpp |
| 3 | ************************************************************************* |
| 4 | * @file abstractserver.h |
| 5 | * @date 30.12.2012 |
| 6 | * @author Peter Spiess-Knafl <dev@spiessknafl.at> |
| 7 | * @license See attached LICENSE.txt |
| 8 | ************************************************************************/ |
| 9 | |
| 10 | #ifndef JSONRPC_CPP_ABSTRACTSERVER_H_ |
| 11 | #define JSONRPC_CPP_ABSTRACTSERVER_H_ |
| 12 | |
| 13 | #include "abstractserverconnector.h" |
| 14 | #include "iclientconnectionhandler.h" |
| 15 | #include "iprocedureinvokationhandler.h" |
| 16 | #include "requesthandlerfactory.h" |
| 17 | #include <jsonrpccpp/common/procedure.h> |
| 18 | #include <map> |
| 19 | #include <string> |
| 20 | #include <vector> |
| 21 | |
| 22 | namespace jsonrpc { |
| 23 | |
| 24 | template <class S> |
| 25 | class AbstractServer : public IProcedureInvokationHandler { |
| 26 | public: |
| 27 | typedef void (S::*methodPointer_t)(const Json::Value ¶meter, Json::Value &result); |
| 28 | typedef void (S::*notificationPointer_t)(const Json::Value ¶meter); |
| 29 | |
| 30 | AbstractServer(AbstractServerConnector &connector, serverVersion_t type = JSONRPC_SERVER_V2) : connection(connector) { |
| 31 | this->handler = RequestHandlerFactory::createProtocolHandler(type, *this); |
| 32 | connector.SetHandler(this->handler); |
| 33 | } |
| 34 | |
| 35 | virtual ~AbstractServer() { delete this->handler; } |
| 36 | |
| 37 | bool StartListening() { return connection.StartListening(); } |
| 38 | |
| 39 | bool StopListening() { return connection.StopListening(); } |
| 40 | |
| 41 | virtual void HandleMethodCall(Procedure &proc, const Json::Value &input, Json::Value &output) { |
| 42 | S *instance = dynamic_cast<S *>(this); |
| 43 | (instance->*methods[proc.GetProcedureName()])(input, output); |
| 44 | } |
| 45 | |
| 46 | virtual void HandleNotificationCall(Procedure &proc, const Json::Value &input) { |
| 47 | S *instance = dynamic_cast<S *>(this); |
| 48 | (instance->*notifications[proc.GetProcedureName()])(input); |
| 49 | } |
| 50 | |
| 51 | protected: |
| 52 | bool bindAndAddMethod(const Procedure &proc, methodPointer_t pointer) { |
| 53 | if (proc.GetProcedureType() == RPC_METHOD && !this->symbolExists(proc.GetProcedureName())) { |
| 54 | this->handler->AddProcedure(proc); |
| 55 | this->methods[proc.GetProcedureName()] = pointer; |
| 56 | return true; |
| 57 | } |
| 58 | return false; |
| 59 | } |
| 60 | |
| 61 | bool bindAndAddNotification(const Procedure &proc, notificationPointer_t pointer) { |
| 62 | if (proc.GetProcedureType() == RPC_NOTIFICATION && !this->symbolExists(proc.GetProcedureName())) { |
| 63 | this->handler->AddProcedure(proc); |
| 64 | this->notifications[proc.GetProcedureName()] = pointer; |
| 65 | return true; |
| 66 | } |
| 67 | return false; |
| 68 | } |
| 69 | |
| 70 | private: |
| 71 | AbstractServerConnector &connection; |
| 72 | IProtocolHandler *handler; |
| 73 | std::map<std::string, methodPointer_t> methods; |
| 74 | std::map<std::string, notificationPointer_t> notifications; |
| 75 | |
| 76 | bool symbolExists(const std::string &name) { |
| 77 | if (methods.find(name) != methods.end()) |
| 78 | return true; |
| 79 | if (notifications.find(name) != notifications.end()) |
| 80 | return true; |
| 81 | return false; |
| 82 | } |
| 83 | }; |
| 84 | |
| 85 | } /* namespace jsonrpc */ |
| 86 | #endif /* JSONRPC_CPP_ABSTRACTSERVER_H_ */ |
| 87 | |