.. _program_listing_file_include_class_loader_multi_library_class_loader.hpp: Program Listing for File multi_library_class_loader.hpp ======================================================= |exhale_lsh| :ref:`Return to documentation for file ` (``include/class_loader/multi_library_class_loader.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * Software License Agreement (BSD License) * * Copyright (c) 2012, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_HPP_ #define CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_HPP_ #include #include #include #include #include // TODO(mikaelarguedas) remove this once console_bridge complies with this // see https://github.com/ros/console_bridge/issues/55 #ifdef __clang__ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" #endif #include "console_bridge/console.h" #ifdef __clang__ # pragma clang diagnostic pop #endif #include "class_loader/class_loader.hpp" #include "class_loader/visibility_control.hpp" namespace class_loader { typedef std::string LibraryPath; typedef std::map LibraryToClassLoaderMap; typedef std::vector ClassLoaderVector; class MultiLibraryClassLoaderImpl; class CLASS_LOADER_PUBLIC MultiLibraryClassLoader { public: explicit MultiLibraryClassLoader(bool enable_ondemand_loadunload); virtual ~MultiLibraryClassLoader(); template std::shared_ptr createInstance(const std::string & class_name) { CONSOLE_BRIDGE_logDebug( "class_loader::MultiLibraryClassLoader: " "Attempting to create instance of class type %s.", class_name.c_str()); ClassLoader * loader = getClassLoaderForClass(class_name); if (nullptr == loader) { 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()"); } return loader->createInstance(class_name); } template std::shared_ptr createInstance( const std::string & class_name, const std::string & library_path) { ClassLoader * loader = getClassLoaderForLibrary(library_path); if (nullptr == loader) { 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()"); } return loader->createInstance(class_name); } template ClassLoader::UniquePtr createUniqueInstance(const std::string & class_name) { CONSOLE_BRIDGE_logDebug( "class_loader::MultiLibraryClassLoader: Attempting to create instance of class type %s.", class_name.c_str()); ClassLoader * loader = getClassLoaderForClass(class_name); if (nullptr == loader) { 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()"); } return loader->createUniqueInstance(class_name); } template ClassLoader::UniquePtr createUniqueInstance(const std::string & class_name, const std::string & library_path) { ClassLoader * loader = getClassLoaderForLibrary(library_path); if (nullptr == loader) { 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()"); } return loader->createUniqueInstance(class_name); } template Base * createUnmanagedInstance(const std::string & class_name) { ClassLoader * loader = getClassLoaderForClass(class_name); if (nullptr == loader) { throw class_loader::CreateClassException( "MultiLibraryClassLoader: Could not create class of type " + class_name); } return loader->createUnmanagedInstance(class_name); } template Base * createUnmanagedInstance(const std::string & class_name, const std::string & library_path) { ClassLoader * loader = getClassLoaderForLibrary(library_path); if (nullptr == loader) { 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()"); } return loader->createUnmanagedInstance(class_name); } template bool isClassAvailable(const std::string & class_name) const { std::vector available_classes = getAvailableClasses(); return available_classes.end() != std::find( available_classes.begin(), available_classes.end(), class_name); } bool isLibraryAvailable(const std::string & library_path) const; template std::vector getAvailableClasses() const { std::vector available_classes; for (auto & loader : getAllAvailableClassLoaders()) { std::vector loader_classes = loader->getAvailableClasses(); available_classes.insert( available_classes.end(), loader_classes.begin(), loader_classes.end()); } return available_classes; } template std::vector getAvailableClassesForLibrary(const std::string & library_path) { ClassLoader * loader = getClassLoaderForLibrary(library_path); if (nullptr == loader) { throw class_loader::NoClassLoaderExistsException( "There is no ClassLoader in MultiLibraryClassLoader bound to library " + library_path + " Ensure you called MultiLibraryClassLoader::loadLibrary()"); } return loader->getAvailableClasses(); } std::vector getRegisteredLibraries() const; void loadLibrary(const std::string & library_path); int unloadLibrary(const std::string & library_path); private: bool isOnDemandLoadUnloadEnabled() const; ClassLoader * getClassLoaderForLibrary(const std::string & library_path); template ClassLoader * getClassLoaderForClass(const std::string & class_name) { ClassLoaderVector loaders = getAllAvailableClassLoaders(); for (ClassLoaderVector::iterator i = loaders.begin(); i != loaders.end(); ++i) { if (!(*i)->isLibraryLoaded()) { (*i)->loadLibrary(); } if ((*i)->isClassAvailable(class_name)) { return *i; } } return nullptr; } ClassLoaderVector getAllAvailableClassLoaders() const; void shutdownAllClassLoaders(); MultiLibraryClassLoaderImpl * impl_; }; } // namespace class_loader #endif // CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_HPP_