CppCMS
cppcms/url_dispatcher.h
00001 
00002 //                                                                             
00003 //  Copyright (C) 2008-2012  Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>     
00004 //                                                                             
00005 //  See accompanying file COPYING.TXT file for licensing details.
00006 //
00008 #ifndef CPPCMS_URL_DISPATCHER_H
00009 #define CPPCMS_URL_DISPATCHER_H
00010 
00011 #include <booster/noncopyable.h>
00012 #include <cppcms/defs.h>
00013 #include <booster/function.h>
00014 #include <booster/hold_ptr.h>
00015 #include <booster/traits/enable_if.h>
00016 #include <booster/traits/is_base_of.h>
00017 #include <cppcms/application.h>
00018 #include <string>
00019 #include <list>
00020 
00021 namespace cppcms {
00022 
00023         class application;
00024 
00044 
00045         class CPPCMS_API url_dispatcher : public booster::noncopyable {
00046         public:
00047                 // Handlers
00048                 typedef booster::function<void()> handler;
00049                 typedef booster::function<void(std::string)> handler1;
00050                 typedef booster::function<void(std::string,std::string)> handler2;
00051                 typedef booster::function<void(std::string,std::string,std::string)> handler3;
00052                 typedef booster::function<void(std::string,std::string,std::string,std::string)> handler4;
00053 
00058                 void assign(std::string const &regex,handler handler);
00069                 void assign(std::string const &regex,handler1 handler,int exp1);
00075                 void assign(std::string const &regex,handler2 handler,int exp1,int exp2);
00081                 void assign(std::string const &regex,handler3 handler,int exp1,int exp2,int exp3);
00087                 void assign(std::string const &regex,handler4 handler,int exp1,int exp2,int exp3,int exp4);
00088 
00095 
00096                 bool dispatch(std::string url);
00097 
00098                 url_dispatcher();
00099                 ~url_dispatcher();
00100 
00109                 template<typename C>
00110                 void assign(std::string const &regex,void (C::*member)(),C *object)
00111                 {
00112                         assign(regex,binder0<C>(member,object));
00113                 }
00121                 template<typename C>
00122                 void assign(std::string const &regex,void (C::*member)(std::string),C *object,int e1)
00123                 {
00124                         assign(regex,binder1<C>(member,object),e1);
00125                 }
00133                 template<typename C>
00134                 void assign(std::string const &regex,void (C::*member)(std::string,std::string),C *object,int e1,int e2)
00135                 {
00136                         assign(regex,binder2<C>(member,object),e1,e2);
00137                 }
00138                 template<typename C>
00146                 void assign(std::string const &regex,void (C::*member)(std::string,std::string,std::string),C *object,int e1,int e2,int e3)
00147                 {
00148                         assign(regex,binder3<C>(member,object),e1,e2,e3);
00149                 }
00157                 template<typename C>
00158                 void assign(std::string const &regex,void (C::*member)(std::string,std::string,std::string,std::string),C *object,int e1,int e2,int e3,int e4)
00159                 {
00160                         assign(regex,binder4<C>(member,object),e1,e2,e3,e4);
00161                 }
00162 
00175                 void mount(std::string const &match,application &app,int part);
00176 
00177         private:
00178 
00179                 template<typename C,typename Enable = void>
00180                 class page_guard {
00181                 public:
00182                         page_guard(C * /*o*/) {}
00183                 };
00184 
00185                 template<typename C>
00186                 class page_guard<C,typename booster::enable_if<booster::is_base_of< cppcms::application,C> >::type > {
00187                 public:
00188                         page_guard(C *o) : 
00189                                 object_(o)
00190                         {
00191                                 object_->init();
00192                         }
00193                         ~page_guard()
00194                         {
00195                                 object_->clear();
00196                         }
00197                 private:
00198                         application *object_;
00199                 };
00200 
00201                 template<typename C>                                            
00202                 struct binder0{
00203                         typedef void (C::*member_type)();
00204                         member_type member;
00205                         C *object;
00206                         
00207                         binder0(member_type m,C *o) :
00208                                 member(m),
00209                                 object(o)
00210                         {
00211                         }
00212                         void operator()() const
00213                         {
00214                                 page_guard<C> guard(object);
00215                                 (object->*member)();
00216                         }
00217                 };
00218                 
00219                 template<typename C>                                            
00220                 struct binder1{
00221                         typedef void (C::*member_type)(std::string);
00222                         member_type member;
00223                         C *object;
00224                         
00225                         binder1(member_type m,C *o) :
00226                                 member(m),
00227                                 object(o)
00228                         {
00229                         }
00230                         void operator()(std::string p1) const
00231                         {
00232                                 page_guard<C> guard(object);
00233                                 (object->*member)(p1);
00234                         }
00235                 };
00236 
00237                 template<typename C>                                            
00238                 struct binder2{
00239                         typedef void (C::*member_type)(std::string,std::string);
00240                         member_type member;
00241                         C *object;
00242                         
00243                         binder2(member_type m,C *o) :
00244                                 member(m),
00245                                 object(o)
00246                         {
00247                         }
00248                         void operator()(std::string p1,std::string p2) const
00249                         {
00250                                 page_guard<C> guard(object);
00251                                 (object->*member)(p1,p2);
00252                         }
00253                 };
00254                 template<typename C>                                            
00255                 struct binder3{
00256                         typedef void (C::*member_type)(std::string,std::string,std::string);
00257                         member_type member;
00258                         C *object;
00259                         
00260                         binder3(member_type m,C *o) :
00261                                 member(m),
00262                                 object(o)
00263                         {
00264                         }
00265                         void operator()(std::string p1,std::string p2,std::string p3) const
00266                         {
00267                                 page_guard<C> guard(object);
00268                                 (object->*member)(p1,p2,p3);
00269                         }
00270                 };
00271                 template<typename C>                                            
00272                 struct binder4{
00273                         typedef void (C::*member_type)(std::string,std::string,std::string,std::string);
00274                         member_type member;
00275                         C *object;
00276                         
00277                         binder4(member_type m,C *o) :
00278                                 member(m),
00279                                 object(o)
00280                         {
00281                         }
00282                         void operator()(std::string p1,std::string p2,std::string p3,std::string p4) const
00283                         {
00284                                 page_guard<C> guard(object);
00285                                 (object->*member)(p1,p2,p3,p4);
00286                         }
00287                 };
00288                 
00289 
00290                 struct _data;
00291                 booster::hold_ptr<_data> d;
00292         };
00293 
00294 } // cppcms
00295 
00296 #endif