1 | /************************************************************************* |
2 | * libjson-rpc-cpp |
3 | ************************************************************************* |
4 | * @file abstractprotocolhandler.cpp |
5 | * @date 10/23/2014 |
6 | * @author Peter Spiess-Knafl <dev@spiessknafl.at> |
7 | * @license See attached LICENSE.txt |
8 | ************************************************************************/ |
9 | |
10 | #include "abstractprotocolhandler.h" |
11 | #include <jsonrpccpp/common/errors.h> |
12 | #include <sstream> |
13 | #include <map> |
14 | |
15 | using namespace jsonrpc; |
16 | using namespace std; |
17 | |
18 | AbstractProtocolHandler::AbstractProtocolHandler(IProcedureInvokationHandler &handler) : handler(handler) {} |
19 | |
20 | AbstractProtocolHandler::~AbstractProtocolHandler() {} |
21 | |
22 | void AbstractProtocolHandler::AddProcedure(const Procedure &procedure) { this->procedures[procedure.GetProcedureName()] = procedure; } |
23 | |
24 | void AbstractProtocolHandler::HandleRequest(const std::string &request, std::string &retValue) { |
25 | Json::Value req; |
26 | Json::Value resp; |
27 | Json::StreamWriterBuilder wbuilder; |
28 | wbuilder["indentation" ] = "" ; |
29 | |
30 | try { |
31 | istringstream(request) >> req; |
32 | this->HandleJsonRequest(req, resp); |
33 | } catch (const Json::Exception &e) { |
34 | this->WrapError(Json::nullValue, Errors::ERROR_RPC_JSON_PARSE_ERROR, Errors::GetErrorMessage(Errors::ERROR_RPC_JSON_PARSE_ERROR), resp); |
35 | } |
36 | |
37 | if (resp != Json::nullValue) |
38 | retValue = Json::writeString(wbuilder, resp); |
39 | } |
40 | |
41 | void AbstractProtocolHandler::ProcessRequest(const Json::Value &request, Json::Value &response) { |
42 | Procedure &method = this->procedures[request[KEY_REQUEST_METHODNAME].asString()]; |
43 | Json::Value result; |
44 | |
45 | if (method.GetProcedureType() == RPC_METHOD) { |
46 | handler.HandleMethodCall(method, request[KEY_REQUEST_PARAMETERS], result); |
47 | this->WrapResult(request, response, result); |
48 | } else { |
49 | handler.HandleNotificationCall(method, request[KEY_REQUEST_PARAMETERS]); |
50 | response = Json::nullValue; |
51 | } |
52 | } |
53 | |
54 | int AbstractProtocolHandler::ValidateRequest(const Json::Value &request) { |
55 | int error = 0; |
56 | Procedure proc; |
57 | if (!this->ValidateRequestFields(request)) { |
58 | error = Errors::ERROR_RPC_INVALID_REQUEST; |
59 | } else { |
60 | map<string, Procedure>::iterator it = this->procedures.find(request[KEY_REQUEST_METHODNAME].asString()); |
61 | if (it != this->procedures.end()) { |
62 | proc = it->second; |
63 | if (this->GetRequestType(request) == RPC_METHOD && proc.GetProcedureType() == RPC_NOTIFICATION) { |
64 | error = Errors::ERROR_SERVER_PROCEDURE_IS_NOTIFICATION; |
65 | } else if (this->GetRequestType(request) == RPC_NOTIFICATION && proc.GetProcedureType() == RPC_METHOD) { |
66 | error = Errors::ERROR_SERVER_PROCEDURE_IS_METHOD; |
67 | } else if (!proc.ValdiateParameters(request[KEY_REQUEST_PARAMETERS])) { |
68 | error = Errors::ERROR_RPC_INVALID_PARAMS; |
69 | } |
70 | } else { |
71 | error = Errors::ERROR_RPC_METHOD_NOT_FOUND; |
72 | } |
73 | } |
74 | return error; |
75 | } |
76 | |