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.
 
 
 
 
 
 

395 lines
8.5 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. #define CPPCMS_SOURCE
  9. #include <cppcms/application.h>
  10. #include <cppcms/http_context.h>
  11. #include <cppcms/service.h>
  12. #include <cppcms/filters.h>
  13. #include <cppcms/cppcms_error.h>
  14. #include <cppcms/url_dispatcher.h>
  15. #include <cppcms/url_mapper.h>
  16. #include <cppcms/applications_pool.h>
  17. #include <cppcms/http_response.h>
  18. #include <cppcms/views_pool.h>
  19. #include <booster/hold_ptr.h>
  20. #include <set>
  21. #include <vector>
  22. #include <sstream>
  23. #include <booster/locale/message.h>
  24. #include <cppcms/config.h>
  25. namespace cppcms {
  26. struct application::_data {
  27. _data(cppcms::service *s):
  28. service(s),
  29. pool_id(-1)
  30. {
  31. }
  32. cppcms::service *service;
  33. booster::shared_ptr<http::context> conn;
  34. int pool_id;
  35. url_dispatcher url;
  36. booster::hold_ptr<url_mapper> url_map;
  37. std::vector<application *> managed_children;
  38. };
  39. application::application(cppcms::service &srv) :
  40. d(new _data(&srv)),
  41. refs_(0)
  42. {
  43. parent_=root_=this;
  44. d->url_map.reset(new url_mapper(this));
  45. }
  46. application::~application()
  47. {
  48. for(unsigned i=0;i<d->managed_children.size();i++) {
  49. delete d->managed_children[i];
  50. d->managed_children[i]=0;
  51. }
  52. }
  53. cppcms::service &application::service()
  54. {
  55. return *d->service;
  56. }
  57. json::value const &application::settings()
  58. {
  59. return service().settings();
  60. }
  61. http::request &application::request()
  62. {
  63. return context().request();
  64. }
  65. http::response &application::response()
  66. {
  67. return context().response();
  68. }
  69. url_dispatcher &application::dispatcher()
  70. {
  71. return d->url;
  72. }
  73. url_mapper &application::mapper()
  74. {
  75. return *d->url_map;
  76. }
  77. booster::shared_ptr<http::context> application::get_context()
  78. {
  79. return root()->d->conn;
  80. }
  81. http::context &application::context()
  82. {
  83. if(!root()->d->conn)
  84. throw cppcms_error("Access to unassigned context");
  85. return *root()->d->conn;
  86. }
  87. booster::shared_ptr<http::context> application::release_context()
  88. {
  89. booster::shared_ptr<http::context> ptr=root()->d->conn;
  90. assign_context(booster::shared_ptr<http::context>());
  91. return ptr;
  92. }
  93. bool application::is_asynchronous()
  94. {
  95. return pool_id() < 0;
  96. }
  97. void application::assign_context(booster::shared_ptr<http::context> conn)
  98. {
  99. root()->d->conn=conn;
  100. }
  101. void application::pool_id(int id)
  102. {
  103. d->pool_id=id;
  104. }
  105. int application::pool_id()
  106. {
  107. return d->pool_id;
  108. }
  109. application *application::parent()
  110. {
  111. return parent_;
  112. }
  113. application *application::root()
  114. {
  115. if(root_ == root_->root_)
  116. return root_;
  117. do {
  118. root_ = root_->root_;
  119. }
  120. while(root_->root_ != root_);
  121. return root_;
  122. }
  123. void application::parent(application *app)
  124. {
  125. parent_=app;
  126. root_=app->root();
  127. }
  128. void application::add(application &app)
  129. {
  130. if(app.parent()!=this)
  131. app.parent(this);
  132. }
  133. void application::add(application &app,std::string const &regex,int part)
  134. {
  135. add(app);
  136. dispatcher().mount(regex,app,part);
  137. }
  138. void application::add(application &app,std::string const &name,std::string const &url)
  139. {
  140. add(app);
  141. mapper().mount(name,url,app);
  142. }
  143. void application::add(application &app,std::string const &name,std::string const &url,std::string const &regex,int part)
  144. {
  145. add(app);
  146. dispatcher().mount(regex,app,part);
  147. mapper().mount(name,url,app);
  148. }
  149. void application::attach(application *app)
  150. {
  151. d->managed_children.push_back(app);
  152. add(*app);
  153. }
  154. void application::init()
  155. {
  156. }
  157. void application::clear()
  158. {
  159. }
  160. void application::main(std::string url)
  161. {
  162. if(!dispatcher().dispatch(url)) {
  163. response().make_error_response(http::response::not_found);
  164. }
  165. }
  166. void application::attach(application *app,std::string const &regex,int part)
  167. {
  168. attach(app);
  169. dispatcher().mount(regex,*app,part);
  170. }
  171. void application::attach(application *app,std::string const &name,std::string const &url)
  172. {
  173. attach(app);
  174. mapper().mount(name,url,*app);
  175. }
  176. void application::attach(application *app,std::string const &name,std::string const &url,std::string const &regex,int part)
  177. {
  178. attach(app);
  179. dispatcher().mount(regex,*app,part);
  180. mapper().mount(name,url,*app);
  181. }
  182. void application::render(std::string template_name,base_content &content)
  183. {
  184. base_content::app_guard g(content,*this);
  185. service().views_pool().render(context().skin(),template_name,response().out(),content);
  186. }
  187. void application::render(std::string skin,std::string template_name,base_content &content)
  188. {
  189. base_content::app_guard g(content,*this);
  190. service().views_pool().render(skin,template_name,response().out(),content);
  191. }
  192. void application::render(std::string template_name,std::ostream &out,base_content &content)
  193. {
  194. base_content::app_guard g(content,*this);
  195. service().views_pool().render(context().skin(),template_name,out,content);
  196. }
  197. void application::render(std::string skin,std::string template_name,std::ostream &out,base_content &content)
  198. {
  199. base_content::app_guard g(content,*this);
  200. service().views_pool().render(skin,template_name,out,content);
  201. }
  202. cache_interface &application::cache()
  203. {
  204. return context().cache();
  205. }
  206. session_interface &application::session()
  207. {
  208. return context().session();
  209. }
  210. void application::recycle()
  211. {
  212. assign_context(booster::shared_ptr<http::context>());
  213. }
  214. std::string application::translate(char const *ctx,char const *message)
  215. {
  216. return booster::locale::translate(ctx,message).str(context().locale());
  217. }
  218. std::string application::translate(char const *message)
  219. {
  220. return booster::locale::translate(message).str(context().locale());
  221. }
  222. std::string application::translate(char const *ctx,char const *single,char const *plural,int n)
  223. {
  224. return booster::locale::translate(ctx,single,plural,n).str(context().locale());
  225. }
  226. std::string application::translate(char const *single,char const *plural,int n)
  227. {
  228. return booster::locale::translate(single,plural,n).str(context().locale());
  229. }
  230. std::string application::url(std::string const &key)
  231. {
  232. std::ostringstream ss;
  233. ss.imbue(context().locale());
  234. mapper().map(ss,key);
  235. return ss.str();
  236. }
  237. std::string application::url( std::string const &key,
  238. filters::streamable const &p1)
  239. {
  240. std::ostringstream ss;
  241. ss.imbue(context().locale());
  242. mapper().map(ss,key,p1);
  243. return ss.str();
  244. }
  245. std::string application::url( std::string const &key,
  246. filters::streamable const &p1,
  247. filters::streamable const &p2)
  248. {
  249. std::ostringstream ss;
  250. ss.imbue(context().locale());
  251. mapper().map(ss,key,p1,p2);
  252. return ss.str();
  253. }
  254. std::string application::url( std::string const &key,
  255. filters::streamable const &p1,
  256. filters::streamable const &p2,
  257. filters::streamable const &p3)
  258. {
  259. std::ostringstream ss;
  260. ss.imbue(context().locale());
  261. mapper().map(ss,key,p1,p2,p3);
  262. return ss.str();
  263. }
  264. std::string application::url( std::string const &key,
  265. filters::streamable const &p1,
  266. filters::streamable const &p2,
  267. filters::streamable const &p3,
  268. filters::streamable const &p4)
  269. {
  270. std::ostringstream ss;
  271. ss.imbue(context().locale());
  272. mapper().map(ss,key,p1,p2,p3,p4);
  273. return ss.str();
  274. }
  275. std::string application::url( std::string const &key,
  276. filters::streamable const &p1,
  277. filters::streamable const &p2,
  278. filters::streamable const &p3,
  279. filters::streamable const &p4,
  280. filters::streamable const &p5)
  281. {
  282. std::ostringstream ss;
  283. ss.imbue(context().locale());
  284. mapper().map(ss,key,p1,p2,p3,p4,p5);
  285. return ss.str();
  286. }
  287. std::string application::url( std::string const &key,
  288. filters::streamable const &p1,
  289. filters::streamable const &p2,
  290. filters::streamable const &p3,
  291. filters::streamable const &p4,
  292. filters::streamable const &p5,
  293. filters::streamable const &p6)
  294. {
  295. std::ostringstream ss;
  296. ss.imbue(context().locale());
  297. mapper().map(ss,key,p1,p2,p3,p4,p5,p6);
  298. return ss.str();
  299. }
  300. } // cppcms
  301. namespace booster {
  302. void intrusive_ptr_add_ref(cppcms::application *app)
  303. {
  304. ++(app->root()->refs_);
  305. }
  306. // REMEMBER THIS IS CALLED FROM DESTRUCTOR!!!
  307. void intrusive_ptr_release(cppcms::application *app)
  308. {
  309. // it is called in destructors... So be very careful
  310. try {
  311. app = app->root();
  312. long refs=--(app->refs_);
  313. if(refs > 0)
  314. return;
  315. cppcms::service &service=app->service();
  316. try {
  317. app->recycle();
  318. }
  319. catch(...) {
  320. if(app->pool_id() < 0) {
  321. service.applications_pool().put(app);
  322. }
  323. else
  324. delete app;
  325. throw;
  326. }
  327. service.applications_pool().put(app);
  328. // return the application to pool... or delete it if "pooled"
  329. }
  330. catch(...)
  331. {
  332. // FIXME LOG IT?
  333. }
  334. }
  335. } // booster