CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

ServletMap.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006 by Ilya A. Volynets-Evenbakh                       *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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 /* _SERVLET_MAP_H_ */

SourceForge.net Logo