00001
00002
00003
00004
00005
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
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 ®ex,handler handler);
00069 void assign(std::string const ®ex,handler1 handler,int exp1);
00075 void assign(std::string const ®ex,handler2 handler,int exp1,int exp2);
00081 void assign(std::string const ®ex,handler3 handler,int exp1,int exp2,int exp3);
00087 void assign(std::string const ®ex,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 ®ex,void (C::*member)(),C *object)
00111 {
00112 assign(regex,binder0<C>(member,object));
00113 }
00121 template<typename C>
00122 void assign(std::string const ®ex,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 ®ex,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 ®ex,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 ®ex,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 * ) {}
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 }
00295
00296 #endif