ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

442 lines
14 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef CPPCMS_APPLICATION_H
  9. #define CPPCMS_APPLICATION_H
  10. #include <cppcms/defs.h>
  11. #include <booster/noncopyable.h>
  12. #include <booster/hold_ptr.h>
  13. #include <booster/atomic_counter.h>
  14. #include <booster/intrusive_ptr.h>
  15. #include <booster/shared_ptr.h>
  16. #include <string>
  17. namespace cppcms {
  18. class application;
  19. }
  20. namespace booster {
  21. void CPPCMS_API intrusive_ptr_add_ref(cppcms::application *p);
  22. void CPPCMS_API intrusive_ptr_release(cppcms::application *p);
  23. }
  24. namespace cppcms {
  25. class service;
  26. class url_dispatcher;
  27. class url_mapper;
  28. class applications_pool;
  29. class application_specific_pool;
  30. class application;
  31. class base_content;
  32. class cache_interface;
  33. class session_interface;
  34. namespace http {
  35. class request;
  36. class response;
  37. class context;
  38. }
  39. namespace json {
  40. class value;
  41. }
  42. namespace filters {
  43. class streamable;
  44. }
  45. ///
  46. /// \brief application class is the base class for all user created applications.
  47. ///
  48. /// This class is the base for all user actions required for web page generation.
  49. /// User application classes are created upon web page request and then cached in \a application_pool.
  50. ///
  51. /// Applications can be bundled to hierarchies. You may add a sub application to hierarchy,
  52. /// and they will always be connected with topmost application and their lifetime would be binded to them.
  53. ///
  54. /// application class is reference counted and may be used with \a intrusive_ptr. But reference count
  55. /// semantics is very different form an ordinary semantics for other classes derived from \a cppcms::refcounted.
  56. ///
  57. /// 1. All hierarchy share the counter of the topmost application. Thus, when all bundle is counted
  58. /// as a single unit allowing passing intrusive_ptr to itself to the central service safely.
  59. /// When the topmost application is destroyed, it destroys all its children application classes.
  60. /// 2. When reference count goes to 0, the application is not destroyed but rather recycled to the
  61. /// application pool for future use.
  62. /// 3. The above hold only for synchronous applications, asynchronous one are destroyed when all
  63. /// reference count goes to 0.
  64. ///
  65. /// There two ways to add sub-applications to hierarchy:
  66. ///
  67. /// 1. Using member function family \a add, usually used with direct members of the parent class.
  68. /// Such child are not destroyed explicitly.
  69. /// 2. Using member function family \a attach. The ownership on the application is moved to the
  70. /// parent class and it destroys an attached class with delete.
  71. ///
  72. class CPPCMS_API application : public booster::noncopyable {
  73. public:
  74. ///
  75. /// Create a new application running on service \a srv, with a parent \a parent
  76. ///
  77. application(cppcms::service &srv);
  78. ///
  79. /// Destroys an application and all assigned application children.
  80. ///
  81. virtual ~application();
  82. ///
  83. /// Get the main service
  84. ///
  85. cppcms::service &service();
  86. ///
  87. /// Get global service settings
  88. ///
  89. json::value const &settings();
  90. ///
  91. /// Get a context of the single HTTP request/response.
  92. ///
  93. http::context &context();
  94. ///
  95. /// Get a HTTP request information class, same as context().request();
  96. ///
  97. http::request &request();
  98. ///
  99. /// Get a HTTP response information class, same as context().response();
  100. ///
  101. http::response &response();
  102. ///
  103. /// Get a dispatched class -- class that responsible on mapping between URLs and a member
  104. /// functions of application class.
  105. ///
  106. /// This member function is application specific and not
  107. /// Connection specific.
  108. ///
  109. url_dispatcher &dispatcher();
  110. ///
  111. /// Get a url_mapper class -- class that responsible on mapping between real objects and
  112. /// urls displayer on the page.
  113. ///
  114. /// This member function is application specific and not
  115. /// Connection specific.
  116. ///
  117. url_mapper &mapper();
  118. ///
  119. /// Get a cache_interface instance. Same as context().cache();
  120. ///
  121. cache_interface &cache();
  122. ///
  123. /// Get current session_interface instance. Same as context().session();
  124. ///
  125. session_interface &session();
  126. ///
  127. /// Render a template \a template_name of default skin using content \a content.
  128. ///
  129. /// Side effect requires: output stream for response class, causes all updated session
  130. /// data be saved and all headers be written. You can't change headers after calling this function.
  131. ///
  132. void render(std::string template_name,base_content &content);
  133. ///
  134. /// Render a template \a template_name of \a skin skin using content \a content.
  135. ///
  136. /// Side effect requires: output stream for response class, causes all updated session
  137. /// data be saved and all headers be written. You can't change headers after calling this function.
  138. ///
  139. void render(std::string skin,std::string template_name,base_content &content);
  140. ///
  141. /// Render a template \a template_name of default skin using content \a content to an output
  142. /// stream \a out. Note: You are responsible to imbue suitable locale to the stream.
  143. ///
  144. /// You should use context().locale() or service().generator() to create such locales.
  145. ///
  146. void render(std::string template_name,std::ostream &out,base_content &content);
  147. ///
  148. /// Render a template \a template_name of a skin \a skin using content \a content to an output
  149. /// stream \a out. Note: You are responsible to imbue suitable locale to the stream.
  150. ///
  151. /// You should use context().locale() or service().generator() to create such locales.
  152. ///
  153. void render(std::string skin,std::string template_name,std::ostream &out,base_content &content);
  154. ///
  155. /// Register an application \a app as child. Ownership of app is not transfered to parent, however
  156. /// it would shared it's parent reference count.
  157. ///
  158. void add(application &app);
  159. ///
  160. /// Register an application \a app as child and mount it into url dispatched calling
  161. /// dispatcher().mount(regex,app,part);
  162. ///
  163. /// Ownership of app is not transfered to parent, however
  164. /// it would shared it's parent reference count.
  165. ///
  166. ///
  167. void add(application &app,std::string const &regex,int part);
  168. ///
  169. /// Register an application \a app as child and mount it into:
  170. ///
  171. /// - url_dispatcher calling dispatcher().mount(regex,app,part);
  172. /// - url_mapper calling mapper().mount(name,url,app);
  173. ///
  174. /// Ownership of app is not transfered to parent, however
  175. /// it would shared it's parent reference count.
  176. ///
  177. ///
  178. void add(application &app,std::string const &name,std::string const &url,std::string const &regex,int part);
  179. ///
  180. /// Register an application \a app as child and mount it into
  181. /// url_mapper calling mapper().mount(name,url,app);
  182. ///
  183. /// Ownership of app is not transfered to parent, however
  184. /// it would shared it's parent reference count.
  185. ///
  186. ///
  187. void add(application &app,std::string const &name,std::string const &url);
  188. ///
  189. /// Register an application \a app as child. Ownership of app is transfered to parent
  190. ///
  191. void attach(application *app);
  192. ///
  193. /// Register an application \a app as child and mount it into
  194. /// url_dispatcher calling dispatcher().mount(regex,*app,part);
  195. ///
  196. /// Ownership of app is transfered to parent.
  197. ///
  198. void attach(application *app,std::string const &regex,int part);
  199. ///
  200. /// Register an application \a app as child and mount it into
  201. /// url_mapper calling mapper().mount(name,url,*app);
  202. ///
  203. /// Ownership of app is transfered to parent.
  204. ///
  205. void attach(application *app,std::string const &name,std::string const &url);
  206. ///
  207. /// Register an application \a app as child and mount it into:
  208. ///
  209. /// - url_dispatcher calling dispatcher().mount(regex,*app,part);
  210. /// - url_mapper calling mapper().mount(name,url,*app);
  211. ///
  212. /// Ownership of app is transfered to parent.
  213. ///
  214. void attach(application *app,std::string const &name,std::string const &url,std::string const &regex,int part);
  215. ///
  216. /// Get the parent of the application, if the application is the topmost class in hierarchy,
  217. /// it would return \a this, So, if you want to check if the application has any parent test
  218. /// app->parent()!=app;
  219. ///
  220. application *parent();
  221. ///
  222. /// Get the root application of the hierarchy. Note, if the application is the topmost one,
  223. /// \a this pointer would be returned
  224. ///
  225. application *root();
  226. ///
  227. /// Request from an application give-up on ownership of the http::context class and give it
  228. /// to the user control. Usually it is required for processing asynchronous requests.
  229. ///
  230. /// Note: because application hierarchy shared same context, it affects all classes in it.
  231. ///
  232. booster::shared_ptr<http::context> release_context();
  233. ///
  234. /// Get reference counted pointer to the http::context
  235. ///
  236. booster::shared_ptr<http::context> get_context();
  237. ///
  238. /// Set context to the application. The application gets shared ownership on the context.
  239. ///
  240. /// Note: because application hierarchy shared same context, it affects all classes in it.
  241. ///
  242. void assign_context(booster::shared_ptr<http::context> conn);
  243. ///
  244. /// Add context to applications such that context ownership isn't transferred
  245. /// to the application
  246. ///
  247. /// \ver{v1_2}
  248. void add_context(http::context &conn);
  249. ///
  250. /// Remove context added with add_context
  251. ///
  252. /// \ver{v1_2}
  253. void remove_context();
  254. ///
  255. /// Returns true if current application was created as asynchronous application.
  256. ///
  257. bool is_asynchronous();
  258. ///
  259. /// Returns true if there is a context added or assigned to application
  260. ///
  261. /// \ver{v1_2}
  262. bool has_context();
  263. ///
  264. /// Returns true if the application owns a context (that can be released for example)
  265. ///
  266. /// \ver{v1_2}
  267. bool owns_context();
  268. ///
  269. /// This is main function of the application that is called when it is matched
  270. /// according to the regular expression in the applications_pool class.
  271. ///
  272. /// By default, main calls dispatcher().dispatch(url). And if the last fails, it
  273. /// creates 404 Error page. This allows developers to create its own hooks for
  274. /// reaction on incoming URL as, initialization and cleanup of general resources,
  275. /// Custom 404 and error handlers etc.
  276. ///
  277. virtual void main(std::string url);
  278. ///
  279. /// This member function called when URL is dispatched to this application, it is
  280. /// useful when member functions of applications are called, by default does nothing
  281. ///
  282. virtual void init();
  283. ///
  284. /// This function is used for cleanup unused stuff, it should not throw
  285. ///
  286. virtual void clear();
  287. ///
  288. /// Translate a message in current locale for given \a message in \a context
  289. ///
  290. std::string translate(char const *context,char const *message);
  291. ///
  292. /// Translate a message in current locale for given \a message
  293. ///
  294. std::string translate(char const *message);
  295. ///
  296. /// Translate a message in current locale for given \a single and \a plural form for number \a n in \a context.
  297. ///
  298. std::string translate(char const *context,char const *single,char const *plural,int n);
  299. ///
  300. /// Translate a message in current locale for given \a single and \a plural form for number \a n
  301. ///
  302. std::string translate(char const *single,char const *plural,int n);
  303. ///
  304. /// Map url-key \a key to actual URL, without parameters
  305. ///
  306. /// Effectively it calls mapper().map(...)
  307. ///
  308. std::string url(std::string const &key);
  309. ///
  310. /// Map url-key \a key to actual URL, with parameter p1
  311. ///
  312. /// Effectively it calls mapper().map(...)
  313. ///
  314. std::string url(std::string const &key,
  315. filters::streamable const &p1);
  316. ///
  317. /// Map url-key \a key to actual URL, with parameters p1, p2
  318. ///
  319. /// Effectively it calls mapper().map(...)
  320. ///
  321. std::string url(std::string const &key,
  322. filters::streamable const &p1,
  323. filters::streamable const &p2);
  324. ///
  325. /// Map url-key \a key to actual URL, with parameters p1, p2, p3
  326. ///
  327. /// Effectively it calls mapper().map(...)
  328. ///
  329. std::string url(std::string const &key,
  330. filters::streamable const &p1,
  331. filters::streamable const &p2,
  332. filters::streamable const &p3);
  333. ///
  334. /// Map url-key \a key to actual URL, with parameters p1, p2, p3, p4
  335. ///
  336. /// Effectively it calls mapper().map(...)
  337. ///
  338. std::string url(std::string const &key,
  339. filters::streamable const &p1,
  340. filters::streamable const &p2,
  341. filters::streamable const &p3,
  342. filters::streamable const &p4);
  343. ///
  344. /// Map url-key \a key to actual URL, with parameters p1, p2, p3, p4, p5
  345. ///
  346. /// Effectively it calls mapper().map(...)
  347. ///
  348. std::string url(std::string const &key,
  349. filters::streamable const &p1,
  350. filters::streamable const &p2,
  351. filters::streamable const &p3,
  352. filters::streamable const &p4,
  353. filters::streamable const &p5);
  354. ///
  355. /// Map url-key \a key to actual URL, with parameters p1, p2, p3, p4, p5, p6
  356. ///
  357. /// Effectively it calls mapper().map(...)
  358. ///
  359. std::string url(std::string const &key,
  360. filters::streamable const &p1,
  361. filters::streamable const &p2,
  362. filters::streamable const &p3,
  363. filters::streamable const &p4,
  364. filters::streamable const &p5,
  365. filters::streamable const &p6);
  366. private:
  367. void recycle();
  368. void parent(application *parent);
  369. booster::weak_ptr<application_specific_pool> get_pool();
  370. void set_pool(booster::weak_ptr<application_specific_pool> pool);
  371. struct _data; // future use
  372. booster::hold_ptr<_data> d;
  373. application *parent_;
  374. application *root_;
  375. booster::atomic_counter refs_;
  376. friend class applications_pool;
  377. friend class application_specific_pool;
  378. friend void booster::intrusive_ptr_add_ref(application *p);
  379. friend void booster::intrusive_ptr_release(application *p);
  380. };
  381. } // cppcms
  382. #endif