multi_library_class_loader.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_H_
31 #define CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_H_
32 
33 #include <boost/thread.hpp>
34 #include <map>
35 #include <string>
36 #include <vector>
37 
39 
40 // TODO(mikaelarguedas) : replace no lints with the explicit keyword in an ABI breaking release
41 
42 namespace class_loader
43 {
44 
45 typedef std::string LibraryPath;
46 typedef std::map<LibraryPath, class_loader::ClassLoader *> LibraryToClassLoaderMap;
47 typedef std::vector<ClassLoader *> ClassLoaderVector;
48 
54 {
55 public:
60  MultiLibraryClassLoader(bool enable_ondemand_loadunload); // NOLINT(runtime/explicit)
61 
65  virtual ~MultiLibraryClassLoader();
66 
74  template<class Base>
75  boost::shared_ptr<Base> createInstance(const std::string & class_name)
76  {
78  "class_loader::MultiLibraryClassLoader: "
79  "Attempting to create instance of class type %s.",
80  class_name.c_str());
81  ClassLoader * loader = getClassLoaderForClass<Base>(class_name);
82  if (NULL == loader) {
84  "MultiLibraryClassLoader: Could not create object of class type " +
85  class_name +
86  " as no factory exists for it. Make sure that the library exists and "
87  "was explicitly loaded through MultiLibraryClassLoader::loadLibrary()");
88  }
89 
90  return loader->createInstance<Base>(class_name);
91  }
92 
101  template<class Base>
102  boost::shared_ptr<Base>
103  createInstance(const std::string & class_name, const std::string & library_path)
104  {
105  ClassLoader * loader = getClassLoaderForLibrary(library_path);
106  if (NULL == loader) {
108  "Could not create instance as there is no ClassLoader in "
109  "MultiLibraryClassLoader bound to library " + library_path +
110  " Ensure you called MultiLibraryClassLoader::loadLibrary()");
111  }
112  return loader->createInstance<Base>(class_name);
113  }
114 
115 #if __cplusplus >= 201103L
116 
123  template<class Base>
124  ClassLoader::UniquePtr<Base> createUniqueInstance(const std::string & class_name)
125  {
127  "class_loader::MultiLibraryClassLoader: Attempting to create instance of class type %s.",
128  class_name.c_str());
129  ClassLoader * loader = getClassLoaderForClass<Base>(class_name);
130  if (nullptr == loader) {
132  "MultiLibraryClassLoader: Could not create object of class type " + class_name +
133  " as no factory exists for it. "
134  "Make sure that the library exists and was explicitly loaded through "
135  "MultiLibraryClassLoader::loadLibrary()");
136  }
137  return loader->createUniqueInstance<Base>(class_name);
138  }
139 
148  template<class Base>
149  ClassLoader::UniquePtr<Base>
150  createUniqueInstance(const std::string & class_name, const std::string & library_path)
151  {
152  ClassLoader * loader = getClassLoaderForLibrary(library_path);
153  if (nullptr == loader) {
155  "Could not create instance as there is no ClassLoader in "
156  "MultiLibraryClassLoader bound to library " + library_path +
157  " Ensure you called MultiLibraryClassLoader::loadLibrary()");
158  }
159  return loader->createUniqueInstance<Base>(class_name);
160  }
161 #endif
162 
171  template<class Base>
172  Base * createUnmanagedInstance(const std::string & class_name)
173  {
174  ClassLoader * loader = getClassLoaderForClass<Base>(class_name);
175  if (NULL == loader) {
177  "MultiLibraryClassLoader: Could not create class of type " + class_name);
178  }
179  return loader->createUnmanagedInstance<Base>(class_name);
180  }
181 
190  template<class Base>
191  Base * createUnmanagedInstance(const std::string & class_name, const std::string & library_path)
192  {
193  ClassLoader * loader = getClassLoaderForLibrary(library_path);
194  if (NULL == loader) {
196  "Could not create instance as there is no ClassLoader in MultiLibraryClassLoader "
197  "bound to library " + library_path +
198  " Ensure you called MultiLibraryClassLoader::loadLibrary()");
199  }
200  return loader->createUnmanagedInstance<Base>(class_name);
201  }
202 
209  template<class Base>
210  bool isClassAvailable(const std::string & class_name)
211  {
212  std::vector<std::string> available_classes = getAvailableClasses<Base>();
213  return available_classes.end() != std::find(
214  available_classes.begin(), available_classes.end(), class_name);
215  }
216 
222  bool isLibraryAvailable(const std::string & library_path);
223 
229  template<class Base>
230  std::vector<std::string> getAvailableClasses()
231  {
232  std::vector<std::string> available_classes;
233  ClassLoaderVector loaders = getAllAvailableClassLoaders();
234  for (unsigned int c = 0; c < loaders.size(); c++) {
235  ClassLoader * current = loaders.at(c);
236  std::vector<std::string> loader_classes = current->getAvailableClasses<Base>();
237  available_classes.insert(
238  available_classes.end(), loader_classes.begin(), loader_classes.end());
239  }
240  return available_classes;
241  }
242 
248  template<class Base>
249  std::vector<std::string> getAvailableClassesForLibrary(const std::string & library_path)
250  {
251  ClassLoader * loader = getClassLoaderForLibrary(library_path);
252  std::vector<std::string> available_classes;
253  if (loader) {
254  available_classes = loader->getAvailableClasses<Base>();
255  return available_classes;
256  } else {
258  "There is no ClassLoader in MultiLibraryClassLoader bound to library " +
259  library_path +
260  " Ensure you called MultiLibraryClassLoader::loadLibrary()");
261  }
262  }
263 
268  std::vector<std::string> getRegisteredLibraries();
269 
274  void loadLibrary(const std::string & library_path);
275 
280  int unloadLibrary(const std::string & library_path);
281 
282 private:
287 
293  ClassLoader * getClassLoaderForLibrary(const std::string & library_path);
294 
300  template<typename Base>
301  ClassLoader * getClassLoaderForClass(const std::string & class_name)
302  {
303  ClassLoaderVector loaders = getAllAvailableClassLoaders();
304  for (ClassLoaderVector::iterator i = loaders.begin(); i != loaders.end(); ++i) {
305  if (!(*i)->isLibraryLoaded()) {
306  (*i)->loadLibrary();
307  }
308  if ((*i)->isClassAvailable<Base>(class_name)) {
309  return *i;
310  }
311  }
312  return NULL;
313  }
314 
318  ClassLoaderVector getAllAvailableClassLoaders();
319 
324 
325 private:
327  LibraryToClassLoaderMap active_class_loaders_;
328  boost::mutex loader_mutex_;
329 };
330 
331 
332 } // namespace class_loader
333 #endif // CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_H_
Definition: base.h:33
std::vector< std::string > getAvailableClasses()
Indicates which classes (i.e. class_loader) that can be loaded by this object.
Definition: class_loader.h:92
#define CONSOLE_BRIDGE_logDebug(fmt,...)
ClassLoader * getClassLoaderForClass(const std::string &class_name)
Gets a handle to the class loader corresponding to a specific class.
A ClassLoader that can bind more than one runtime library.
std::vector< std::string > getAvailableClassesForLibrary(const std::string &library_path)
Gets a list of all classes loaded for a particular library.
bool isLibraryAvailable(const std::string &library_path)
Indicates if a library has been loaded into memory.
Base * createUnmanagedInstance(const std::string &derived_class_name)
Generates an instance of loadable classes (i.e. class_loader).
Definition: class_loader.h:155
std::vector< std::string > getAvailableClasses()
Gets a list of all classes that are loaded by the class loader.
int unloadLibrary(const std::string &library_path)
Unloads a library for this class loader.
An exception class thrown when class_loader is unable to create a plugin.
This class allows loading and unloading of dynamically linked libraries which contain class definitio...
Definition: class_loader.h:64
std::vector< ClassLoader * > ClassLoaderVector
Base * createUnmanagedInstance(const std::string &class_name, const std::string &library_path)
Creates an instance of an object of given class name with ancestor class Base This version takes a sp...
void loadLibrary(const std::string &library_path)
Loads a library into memory for this class loader.
An exception class thrown when a multilibrary class loader does not have a ClassLoader bound to it...
void shutdownAllClassLoaders()
Destroys all ClassLoaders.
std::map< LibraryPath, class_loader::ClassLoader * > LibraryToClassLoaderMap
virtual ~MultiLibraryClassLoader()
Virtual destructor for class.
std::vector< std::string > getRegisteredLibraries()
Gets a list of all libraries opened by this class loader .
MultiLibraryClassLoader(bool enable_ondemand_loadunload)
Constructor for the class.
boost::shared_ptr< Base > createInstance(const std::string &derived_class_name)
Generates an instance of loadable classes (i.e. class_loader).
Definition: class_loader.h:112
ClassLoaderVector getAllAvailableClassLoaders()
Gets all class loaders loaded within scope.
bool isOnDemandLoadUnloadEnabled()
Indicates if on-demand (lazy) load/unload is enabled so libraries are loaded/unloaded automatically a...
ClassLoader * getClassLoaderForLibrary(const std::string &library_path)
Gets a handle to the class loader corresponding to a specific runtime library.
boost::shared_ptr< Base > createInstance(const std::string &class_name)
Creates an instance of an object of given class name with ancestor class Base This version does not l...
bool isClassAvailable(const std::string &class_name)
Indicates if a class has been loaded and can be instantiated.
Base * createUnmanagedInstance(const std::string &class_name)
Creates an instance of an object of given class name with ancestor class Base This version does not l...
boost::shared_ptr< Base > createInstance(const std::string &class_name, const std::string &library_path)
Creates an instance of an object of given class name with ancestor class Base This version takes a sp...


class_loader
Author(s): Mirza Shah
autogenerated on Thu Dec 7 2017 03:43:35