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
15using namespace jsonrpc;
16using namespace std;
17
18AbstractProtocolHandler::AbstractProtocolHandler(IProcedureInvokationHandler &handler) : handler(handler) {}
19
20AbstractProtocolHandler::~AbstractProtocolHandler() {}
21
22void AbstractProtocolHandler::AddProcedure(const Procedure &procedure) { this->procedures[procedure.GetProcedureName()] = procedure; }
23
24void 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
41void 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
54int 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