ServletMap.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _SERVLET_MAP_H_
00021 #define _SERVLET_MAP_H_
00022
00023 #include <map>
00024 #include <string>
00025 #include <algorithm>
00026
00027 namespace container
00028 {
00029
00030 template<class T>
00031 class ServletMap
00032 {
00033 public:
00034 typedef std::map<std::string,ServletMap<T>*> subpaths_t;
00035 typedef std::map<std::string,T*> servletmap_t;
00036 private:
00037 servletmap_t m_servlets;
00038 subpaths_t m_subpaths;
00039 template<class F>
00040 class Func: public std::unary_function<const std::string&, void>
00041 {
00042 private:
00043 std::string m_base;
00044 F& m_f;
00045 public:
00046 Func(const std::string& base, F& f)
00047 : m_base(base+'/')
00048 , m_f(f)
00049 {}
00050 void operator ()(const std::pair<std::string,T*>& it)
00051 {
00052 m_f(m_base + it.first);
00053 }
00054 };
00055 template<class F>
00056 class Func2: public std::unary_function<std::pair<std::string, ServletMap*>, void>
00057 {
00058 private:
00059 std::string m_base;
00060 F& m_f;
00061 public:
00062 Func2(const std::string& base, F& f)
00063 : m_base(base+'/')
00064 , m_f(f)
00065 {}
00066 void operator ()(std::pair<std::string, ServletMap*> it)
00067 {
00068 it.second->forEachServletPath(m_f, m_base + it.first);
00069 }
00070 };
00071 class Killer: public std::unary_function<std::pair<std::string, ServletMap<T>*>, void>
00072 {
00073 public:
00074 void operator()(std::pair<std::string, ServletMap<T>*> hit){ delete hit.second; }
00075 };
00076 public:
00077 ~ServletMap();
00078 ServletMap* getPath(std::string path, bool create);
00079 T* getServletDesc(std::string path);
00080 void removeDesc(const std::string& path);
00081 static void splitServPath(const std::string& path, std::string& dir, std::string& name);
00082 const servletmap_t& getServlets() const { return m_servlets; }
00083 const subpaths_t& getSubpaths() const { return m_subpaths; }
00084 template<class F>
00085 void forEachServletPath(F& func, std::string curpath)
00086 {
00087 std::for_each(m_servlets.begin(), m_servlets.end(), Func<F>(curpath, func));
00088 std::for_each(m_subpaths.begin(), m_subpaths.end(), Func2<F>(curpath, func));
00089 }
00090 T*& operator[](const std::string& path)
00091 {
00092 std::string dir, name;
00093 splitServPath(path, dir, name);
00094 ServletMap<T>* sm = getPath(dir, true);
00095 if(sm->m_servlets.find(name) == sm->m_servlets.end())
00096 sm->m_servlets[name] = 0;
00097 return sm->m_servlets[name];
00098 }
00099 };
00100
00101 template<class T>
00102 void ServletMap<T>::splitServPath(const std::string& path, std::string& dir, std::string& name)
00103 {
00104 std::string::size_type slash = path.rfind('/');
00105 if(slash == std::string::npos) {
00106 dir = "/";
00107 name = path;
00108 } else {
00109 dir.assign(path.substr(0, slash));
00110 name.assign(path.substr(slash + 1));
00111 }
00112 }
00113
00114 template<class T>
00115 ServletMap<T>* ServletMap<T>::getPath(std::string path, bool create)
00116 {
00117 if(path[0] == '/')
00118 path.erase(0,1);
00119 if(path.empty())
00120 return this;
00121 std::string::size_type slash = path.find('/');
00122 std::string dir;
00123 std::string rest;
00124 if(slash == std::string::npos) {
00125 dir.assign(path);
00126 } else {
00127 dir.assign(path.substr(0, slash));
00128 rest.assign(path.substr(slash+1));
00129 }
00130 ServletMap* sp;
00131 if(m_subpaths.find(dir) == m_subpaths.end()) {
00132 if(!create) {
00133 return 0;
00134 } else {
00135 sp = new ServletMap<T>;
00136 m_subpaths[dir] = sp;
00137 }
00138 } else {
00139 sp = m_subpaths[dir];
00140 }
00141 return sp->getPath(rest, create);
00142 }
00143
00144 template<class T>
00145 ServletMap<T>::~ServletMap()
00146 {
00147 std::for_each(m_subpaths.begin(), m_subpaths.end(), Killer());
00148 }
00149
00155 template<class T>
00156 T* ServletMap<T>::getServletDesc(std::string path)
00157 {
00158 if(path[0] == '/')
00159 path.erase(0,1);
00160 std::string::size_type slash;
00161 slash = path.find('/');
00162 std::string name;
00163 if(slash == std::string::npos)
00164 name = path;
00165 else
00166 name = path.substr(0, slash);
00167 if(m_servlets.find(name) != m_servlets.end())
00168 return m_servlets[name];
00169 if(m_subpaths.find(name) == m_subpaths.end())
00170 return 0;
00171 return m_subpaths[name]->getServletDesc(path.substr(slash + 1));
00172 }
00173
00174 template<class T>
00175 void ServletMap<T>::removeDesc(const std::string& path)
00176 {
00177 std::string dir, name;
00178 splitServPath(path, dir, name);
00179 ServletMap<T>* sm = getPath(dir, false);
00180 if(sm)
00181 sm->m_servlets.erase(name);
00182 }
00183
00184 }
00185 #endif