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
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef CLASS_LOADER_MULTI_LIBRARY_CLASS_LOADER_H_DEFINED
00031 #define CLASS_LOADER_MULTI_LIBRARY_CLASS_LOADER_H_DEFINED
00032
00033 #include "class_loader.h"
00034 #include <boost/thread.hpp>
00035
00036 namespace class_loader
00037 {
00038
00039 typedef std::string LibraryPath;
00040 typedef std::map<LibraryPath, class_loader::ClassLoader*> LibraryToClassLoaderMap;
00041 typedef std::vector<ClassLoader*> ClassLoaderVector;
00042
00047 class MultiLibraryClassLoader
00048 {
00049 public:
00054 MultiLibraryClassLoader(bool enable_ondemand_loadunload);
00055
00059 virtual ~MultiLibraryClassLoader();
00060
00068 template <class Base>
00069 boost::shared_ptr<Base> createInstance(const std::string& class_name)
00070 {
00071 CONSOLE_BRIDGE_logDebug("class_loader::MultiLibraryClassLoader: Attempting to create instance of class type %s.", class_name.c_str());
00072 ClassLoader* loader = getClassLoaderForClass<Base>(class_name);
00073 if (loader == NULL)
00074 throw class_loader::CreateClassException("MultiLibraryClassLoader: Could not create object of class type " + class_name + " as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()");
00075 return loader->createInstance<Base>(class_name);
00076 }
00077
00086 template <class Base>
00087 boost::shared_ptr<Base> createInstance(const std::string& class_name, const std::string& library_path)
00088 {
00089 ClassLoader* loader = getClassLoaderForLibrary(library_path);
00090 if (loader == NULL)
00091 throw class_loader::NoClassLoaderExistsException("Could not create instance as there is no ClassLoader in MultiLibraryClassLoader bound to library " + library_path + " Ensure you called MultiLibraryClassLoader::loadLibrary()");
00092 return loader->createInstance<Base>(class_name);
00093 }
00094
00095 #if __cplusplus >= 201103L
00096
00103 template <class Base>
00104 ClassLoader::UniquePtr<Base> createUniqueInstance(const std::string& class_name)
00105 {
00106 CONSOLE_BRIDGE_logDebug("class_loader::MultiLibraryClassLoader: Attempting to create instance of class type %s.", class_name.c_str());
00107 ClassLoader* loader = getClassLoaderForClass<Base>(class_name);
00108 if (loader == nullptr)
00109 throw class_loader::CreateClassException("MultiLibraryClassLoader: Could not create object of class type " + class_name + " as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()");
00110 return loader->createUniqueInstance<Base>(class_name);
00111 }
00112
00121 template <class Base>
00122 ClassLoader::UniquePtr<Base> createUniqueInstance(const std::string& class_name, const std::string& library_path)
00123 {
00124 ClassLoader* loader = getClassLoaderForLibrary(library_path);
00125 if (loader == nullptr)
00126 throw class_loader::NoClassLoaderExistsException("Could not create instance as there is no ClassLoader in MultiLibraryClassLoader bound to library " + library_path + " Ensure you called MultiLibraryClassLoader::loadLibrary()");
00127 return loader->createUniqueInstance<Base>(class_name);
00128 }
00129 #endif
00130
00139 template <class Base>
00140 Base* createUnmanagedInstance(const std::string& class_name)
00141 {
00142 ClassLoader* loader = getClassLoaderForClass<Base>(class_name);
00143 if (loader == NULL)
00144 throw class_loader::CreateClassException("MultiLibraryClassLoader: Could not create class of type " + class_name);
00145 return loader->createUnmanagedInstance<Base>(class_name);
00146 }
00147
00156 template <class Base>
00157 Base* createUnmanagedInstance(const std::string& class_name, const std::string& library_path)
00158 {
00159 ClassLoader* loader = getClassLoaderForLibrary(library_path);
00160 if (loader == NULL)
00161 throw class_loader::NoClassLoaderExistsException("Could not create instance as there is no ClassLoader in MultiLibraryClassLoader bound to library " + library_path + " Ensure you called MultiLibraryClassLoader::loadLibrary()");
00162 return loader->createUnmanagedInstance<Base>(class_name);
00163 }
00164
00171 template <class Base>
00172 bool isClassAvailable(const std::string& class_name)
00173 {
00174 std::vector<std::string> available_classes = getAvailableClasses<Base>();
00175 return(available_classes.end() != std::find(available_classes.begin(), available_classes.end(), class_name));
00176 }
00177
00183 bool isLibraryAvailable(const std::string& library_path);
00184
00190 template <class Base>
00191 std::vector<std::string> getAvailableClasses()
00192 {
00193 std::vector<std::string> available_classes;
00194 ClassLoaderVector loaders = getAllAvailableClassLoaders();
00195 for(unsigned int c = 0; c < loaders.size(); c++)
00196 {
00197 ClassLoader* current = loaders.at(c);
00198 std::vector<std::string> loader_classes = current->getAvailableClasses<Base>();
00199 available_classes.insert(available_classes.end(), loader_classes.begin(), loader_classes.end());
00200 }
00201 return(available_classes);
00202 }
00203
00209 template <class Base>
00210 std::vector<std::string> getAvailableClassesForLibrary(const std::string& library_path)
00211 {
00212 ClassLoader* loader = getClassLoaderForLibrary(library_path);
00213 std::vector<std::string> available_classes;
00214 if(loader)
00215 {
00216 available_classes = loader->getAvailableClasses<Base>();
00217 return(available_classes);
00218 }
00219 else
00220 throw class_loader::NoClassLoaderExistsException("There is no ClassLoader in MultiLibraryClassLoader bound to library " + library_path + " Ensure you called MultiLibraryClassLoader::loadLibrary()");
00221 }
00222
00227 std::vector<std::string> getRegisteredLibraries();
00228
00233 void loadLibrary(const std::string& library_path);
00234
00239 int unloadLibrary(const std::string& library_path);
00240
00241
00242 private:
00246 bool isOnDemandLoadUnloadEnabled(){return(enable_ondemand_loadunload_);}
00247
00253 ClassLoader* getClassLoaderForLibrary(const std::string& library_path);
00254
00260 template<typename Base>
00261 ClassLoader* getClassLoaderForClass(const std::string& class_name)
00262 {
00263 ClassLoaderVector loaders = getAllAvailableClassLoaders();
00264 for (ClassLoaderVector::iterator i = loaders.begin(); i != loaders.end(); ++i)
00265 {
00266 if (!(*i)->isLibraryLoaded())
00267 (*i)->loadLibrary();
00268 if ((*i)->isClassAvailable<Base>(class_name))
00269 return *i;
00270 }
00271 return NULL;
00272 }
00273
00277 ClassLoaderVector getAllAvailableClassLoaders();
00278
00282 void shutdownAllClassLoaders();
00283
00284 private:
00285 bool enable_ondemand_loadunload_;
00286 LibraryToClassLoaderMap active_class_loaders_;
00287 boost::mutex loader_mutex_;
00288 };
00289
00290
00291 }
00292 #endif