comploader.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2005 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 
30 #ifndef TNT_COMPLOADER_H
31 #define TNT_COMPLOADER_H
32 
33 #include <cxxtools/smartptr.h>
34 #include <tnt/urlmapper.h>
35 #include <tnt/langlib.h>
36 #include <map>
37 #include <list>
38 #include <string>
39 #include <utility>
40 #include <dlfcn.h>
41 
43 
44 namespace tnt
45 {
46  class Comploader;
47  class ComponentFactory;
48 
49  class LibraryNotFound : public std::exception
50  {
51  std::string _libname;
52  std::string _msg;
53 
54  public:
55  explicit LibraryNotFound(const std::string& libname)
56  : _libname(libname),
57  _msg("Library not found: " + libname)
58  { }
59  ~LibraryNotFound() throw() { }
60 
61  const char* what() const throw()
62  { return _msg.c_str(); }
63 
64  const std::string& getLibname() const
65  { return _libname; }
66  };
67 
68  template <typename objectType>
69  class Dlcloser
70  {
71  protected:
72  void destroy(objectType* ptr)
73  {
74  ::dlclose(*ptr);
75  delete ptr;
76  }
77  };
78 
79  class ComponentLibrary
80  {
81  friend class Comploader;
82 
83  typedef void* HandleType;
85 
86  typedef std::map<std::string, ComponentFactory*> factoryMapType;
87 
88  typedef std::map<std::string, LangLib::PtrType> langlibsType;
89 
90  HandlePointer _handlePtr;
91  factoryMapType _factoryMap;
92  std::string _libname;
93  std::string _path;
94  langlibsType _langlibs;
95 
96  void* dlopen(const std::string& name, bool local);
97  void init(const std::string& name, bool local);
98 
99  public:
100  ComponentLibrary()
101  { }
102 
103  ComponentLibrary(const std::string& path, const std::string& name, bool local)
104  : _libname(name),
105  _path(path)
106  { init(path + '/' + name, local); }
107 
108  ComponentLibrary(const std::string& name, bool local)
109  : _libname(name)
110  { init(name, local); }
111 
112  operator const void* () const { return _handlePtr.getPointer(); }
113 
114  Component* create(const std::string& compname, Comploader& cl, const Urlmapper& rootmapper);
115  LangLib::PtrType getLangLib(const std::string& lang);
116 
117  const std::string& getName() const { return _libname; }
118 
119  void registerFactory(const std::string& compname, ComponentFactory* factory)
120  { _factoryMap.insert(factoryMapType::value_type(compname, factory)); }
121  };
122 
123  class Comploader
124  {
125  typedef std::map<std::string, ComponentLibrary> librarymap_type;
126  typedef std::map<Compident, Component*> componentmap_type;
127 
128  // loaded libraries
129  static librarymap_type& getLibrarymap();
130 
131  // map soname/compname to compinstance
132  componentmap_type componentmap;
133  static ComponentLibrary::factoryMapType* currentFactoryMap;
134 
135  public:
136  Component& fetchComp(const Compident& compident, const Urlmapper& rootmapper = Urlmapper());
137  Component* createComp(const Compident& compident, const Urlmapper& rootmapper);
138  const char* getLangData(const Compident& compident, const std::string& lang);
139 
140  // lookup library; load if needed
141  ComponentLibrary& fetchLib(const std::string& libname);
142 
143  static void registerFactory(const std::string& compname, ComponentFactory* factory);
144  };
145 }
146 
147 #endif // TNT_COMPLOADER_H
148