CppCMS
rpc_json.h
1 //
3 // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
4 //
5 // See accompanying file COPYING.TXT file for licensing details.
6 //
8 #ifndef CPPCMS_RPC_JSON_OBJECT_H
9 #define CPPCMS_RPC_JSON_OBJECT_H
10 
11 #include <cppcms/application.h>
12 #include <booster/function.h>
13 #include <cppcms/json.h>
14 #include <cppcms/cppcms_error.h>
15 
16 namespace cppcms {
20 namespace rpc {
21 
29  class CPPCMS_API call_error : public cppcms_error {
30  public:
34  call_error(std::string const &message);
35  };
36 
37  class json_rpc_server;
38 
46  class CPPCMS_API json_call : public booster::noncopyable {
47  public:
48 
52  ~json_call();
53 
57  std::string method();
58 
66  bool notification();
67 
71  json::array const &params();
72 
77  http::context &context();
78 
82  void return_result(json::value const &);
86  void return_error(json::value const &);
87 
88  private:
89 
90 
91  json_call(http::context &context);
92  friend class json_rpc_server;
93  void return_result(http::context &,json::value const &);
94  void return_error(http::context &,json::value const &);
95  void attach_context(booster::shared_ptr<http::context> context);
96 
97  void check_not_notification();
99  json::value id_;
100  json::array params_;
101  std::string method_;
102  bool notification_;
103 
104  struct _data;
106  };
107 
114  class CPPCMS_API json_rpc_server : public application {
115  public:
119  typedef enum {
122  notification_role
123  } role_type;
124 
129 
133  void bind(std::string const &name,method_type const &,role_type type = any_role);
134 
138  void smd(json::value const &);
139 
143  void smd_raw(std::string const &);
147  void smd_from_file(std::string const &);
148 
152  virtual void main(std::string);
153 
158  booster::shared_ptr<json_call> release_call();
159 
161  ~json_rpc_server();
162 
163 
167  std::string method();
175  bool notification();
179  json::array const &params();
183  void return_result(json::value const &);
187  void return_error(json::value const &);
188  private:
189  void check_call();
190  struct method_data {
191  method_type method;
192  role_type role;
193  };
194  typedef std::map<std::string,method_data> methods_map_type;
195  methods_map_type methods_;
196  booster::shared_ptr<json_call> current_call_;
197 
198  std::string smd_;
199 
200  struct _data;
202  };
203 
205 
206  namespace details {
207 
208  template<typename T> struct fw_ret { typedef T type; };
209  template<typename T> struct fw_ret<T const &> { typedef T type; };
210  template<typename T> struct fw_ret<T const> { typedef T type; };
211 
212  template<> struct fw_ret<json::value> { typedef json::value const &type; };
213  template<> struct fw_ret<json::object> { typedef json::object const &type; };
214  template<> struct fw_ret<json::array> { typedef json::array const &type; };
215  template<> struct fw_ret<std::string> { typedef std::string const &type; };
216 
217  template<> struct fw_ret<json::value const &> { typedef json::value const &type; };
218  template<> struct fw_ret<json::object const &> { typedef json::object const &type; };
219  template<> struct fw_ret<json::array const &> { typedef json::array const &type; };
220  template<> struct fw_ret<std::string const &> { typedef std::string const &type; };
221 
222  template<> struct fw_ret<json::value const> { typedef json::value const &type; };
223  template<> struct fw_ret<json::object const> { typedef json::object const &type; };
224  template<> struct fw_ret<json::array const> { typedef json::array const &type; };
225  template<> struct fw_ret<std::string const> { typedef std::string const &type; };
226 
227 
228  template<typename T>
229  struct fw_ret_handle {
230  static typename fw_ret<T>::type extract(json::value const &v)
231  {
232  return v.get_value<typename fw_ret<T>::type>();
233  }
234  };
235 
236  template<>
237  struct fw_ret_handle<json::value const &>
238  {
239  static json::value const &extract(json::value const &v)
240  {
241  return v;
242  }
243  };
244 
245  template<>
246  struct fw_ret_handle<json::array const &>
247  {
248  static json::array const &extract(json::value const &v)
249  {
250  return v.array();
251  }
252  };
253 
254  template<>
255  struct fw_ret_handle<json::object const &>
256  {
257  static json::object const &extract(json::value const &v)
258  {
259  return v.object();
260  }
261  };
262 
263  template<>
264  struct fw_ret_handle<std::string const &>
265  {
266  static std::string const &extract(json::value const &v)
267  {
268  return v.str();
269  }
270  };
271 
272 
273  template <typename T>
274  inline typename fw_ret<T>::type forward_value(json::value const &v)
275  {
276  typedef typename fw_ret<T>::type return_type;
277  return fw_ret_handle<return_type>::extract(v);
278  }
279 
280  }
281 
282  #define CPPCMS_JSON_RPC_BINDER(N) \
283  namespace details { \
284  template<typename Class,typename Ptr CPPCMS_TEMPLATE_PARAMS> \
285  struct binder##N { \
286  Ptr object; \
287  void (Class::*member)(CPPCMS_FUNC_PARAMS); \
288  void operator()(json::array const &a) const \
289  { \
290  if(a.size()!=N) \
291  throw call_error("Invalid parametres number"); \
292  ((*object).*member)(CPPCMS_CALL_PARAMS); \
293  } \
294  }; \
295  } \
296  template<typename Class,typename Ptr CPPCMS_TEMPLATE_PARAMS> \
297  details::binder##N<Class,Ptr CPPCMS_BINDER_PARAMS> \
298  json_method(void (Class::*m)(CPPCMS_FUNC_PARAMS),Ptr p) \
299  { details::binder##N<Class,Ptr CPPCMS_BINDER_PARAMS> tmp={p,m}; return tmp; } \
300 
301  #define CPPCMS_TEMPLATE_PARAMS
302  #define CPPCMS_FUNC_PARAMS
303  #define CPPCMS_CALL_PARAMS
304  #define CPPCMS_BINDER_PARAMS
305  CPPCMS_JSON_RPC_BINDER(0)
306  #undef CPPCMS_TEMPLATE_PARAMS
307  #undef CPPCMS_FUNC_PARAMS
308  #undef CPPCMS_CALL_PARAMS
309  #undef CPPCMS_BINDER_PARAMS
310 
311  #define CPPCMS_TEMPLATE_PARAMS ,typename P1
312  #define CPPCMS_FUNC_PARAMS P1
313  #define CPPCMS_CALL_PARAMS forward_value<P1>(a[0])
314  #define CPPCMS_BINDER_PARAMS ,P1
315  CPPCMS_JSON_RPC_BINDER(1)
316  #undef CPPCMS_TEMPLATE_PARAMS
317  #undef CPPCMS_FUNC_PARAMS
318  #undef CPPCMS_CALL_PARAMS
319  #undef CPPCMS_BINDER_PARAMS
320 
321  #define CPPCMS_TEMPLATE_PARAMS ,typename P1,typename P2
322  #define CPPCMS_FUNC_PARAMS P1,P2
323  #define CPPCMS_CALL_PARAMS forward_value<P1>(a[0]), forward_value<P2>(a[1])
324  #define CPPCMS_BINDER_PARAMS ,P1,P2
325  CPPCMS_JSON_RPC_BINDER(2)
326  #undef CPPCMS_TEMPLATE_PARAMS
327  #undef CPPCMS_FUNC_PARAMS
328  #undef CPPCMS_CALL_PARAMS
329  #undef CPPCMS_BINDER_PARAMS
330 
331  #define CPPCMS_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3
332  #define CPPCMS_FUNC_PARAMS P1,P2,P3
333  #define CPPCMS_CALL_PARAMS forward_value<P1>(a[0]), forward_value<P2>(a[1]), forward_value<P3>(a[2])
334  #define CPPCMS_BINDER_PARAMS ,P1,P2,P3
335  CPPCMS_JSON_RPC_BINDER(3)
336  #undef CPPCMS_TEMPLATE_PARAMS
337  #undef CPPCMS_FUNC_PARAMS
338  #undef CPPCMS_CALL_PARAMS
339  #undef CPPCMS_BINDER_PARAMS
340 
341  #define CPPCMS_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4
342  #define CPPCMS_FUNC_PARAMS P1,P2,P3,P4
343  #define CPPCMS_CALL_PARAMS forward_value<P1>(a[0]), forward_value<P2>(a[1]), forward_value<P3>(a[2]), forward_value<P4>(a[3])
344  #define CPPCMS_BINDER_PARAMS ,P1,P2,P3,P4
345  CPPCMS_JSON_RPC_BINDER(4)
346  #undef CPPCMS_TEMPLATE_PARAMS
347  #undef CPPCMS_FUNC_PARAMS
348  #undef CPPCMS_CALL_PARAMS
349  #undef CPPCMS_BINDER_PARAMS
350 
351  #undef CPPCMS_JSON_RPC_BINDER
352 
354 
355 } // rpc
356 } // cppcms
357 
358 
359 
360 #endif
booster::function< void(json::array const &)> method_type
Definition: rpc_json.h:128
This class is central representation of json objects.
Definition: json.h:140
Method may receive notification and return result.
Definition: rpc_json.h:120
This class represent the central event loop of the CppCMS applications.
Definition: service.h:62
The error thrown in case of bad call - parameters mismatch or invalid request.
Definition: rpc_json.h:29
Exception thrown by CppCMS framework.
Definition: cppcms_error.h:22
std::map< string_key, value > object
The json::object - std::map of json::value&#39;s.
Definition: json.h:51
json::array const & array() const
This is the namespace where all CppCMS functionality is placed.
Definition: application.h:19
role_type
Definition: rpc_json.h:119
T get_value() const
Definition: json.h:234
context is a central class that holds all specific connection related information. It encapsulates CGI request and response, cache, session and locale information
Definition: http_context.h:47
std::string const & str() const
This class represents single call of json-rpc method.
Definition: rpc_json.h:46
Method can&#39;t be used with notification calls.
Definition: rpc_json.h:121
application class is the base class for all user created applications.
Definition: application.h:82
basic_message< char > message
Definition: message.h:494
JSON-RPC service application.
Definition: rpc_json.h:114
json::object const & object() const
std::vector< value > array
The json::array - std::vector of json::value&#39;s.
Definition: json.h:47
This class makes impossible to copy any class derived from this one.
Definition: noncopyable.h:15