git commit -m "first commit"

This commit is contained in:
2026-05-28 10:29:58 +07:00
commit 167c52aeb6
2048 changed files with 740251 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Open Source Robotics Foundation, 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 PLUGINLIB__CLASS_DESC_H_
#define PLUGINLIB__CLASS_DESC_H_
#include "./class_desc.hpp"
#endif // PLUGINLIB__CLASS_DESC_H_

View File

@@ -0,0 +1,84 @@
/*********************************************************************
*
* Software License Agreement (BSD License)
*
* Copyright (c) 2008, 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 Willow Garage, Inc. 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 PLUGINLIB__CLASS_DESC_HPP_
#define PLUGINLIB__CLASS_DESC_HPP_
#include <string>
namespace pluginlib
{
/// Storage for information about a given class.
class ClassDesc
{
public:
/**
* \param lookup_name The lookup name of the class
* \param derived_class The type of the derived class of the class
* \param base_class The type of the class, corresponds to the type of the base class
* \param package The package the class lives in
* \param description A description for the class
* \param library_name The name of the containing library for the class (not a full path!)
* \param plugin_manifest_path The path to the plugin manifest file
*/
ClassDesc(
const std::string & lookup_name, const std::string & derived_class,
const std::string & base_class, const std::string & package,
const std::string & description, const std::string & library_name,
const std::string & plugin_manifest_path)
: lookup_name_(lookup_name),
derived_class_(derived_class),
base_class_(base_class),
package_(package),
description_(description),
library_name_(library_name),
resolved_library_path_("UNRESOLVED"),
plugin_manifest_path_(plugin_manifest_path) {}
std::string lookup_name_;
std::string derived_class_;
std::string base_class_;
std::string package_;
std::string description_;
std::string library_name_;
std::string resolved_library_path_; // This is set by pluginlib::ClassLoader at load time.
std::string plugin_manifest_path_;
};
} // namespace pluginlib
#endif // PLUGINLIB__CLASS_DESC_HPP_

View File

@@ -0,0 +1,37 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Open Source Robotics Foundation, 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 PLUGINLIB__CLASS_LIST_MACROS_H_
#define PLUGINLIB__CLASS_LIST_MACROS_H_
#include "./class_list_macros.hpp"
#endif // PLUGINLIB__CLASS_LIST_MACROS_H_

View File

@@ -0,0 +1,51 @@
/*********************************************************************
*
* Software License Agreement (BSD License)
*
* Copyright (c) 2008, 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 Willow Garage, Inc. 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 PLUGINLIB__CLASS_LIST_MACROS_HPP_
#define PLUGINLIB__CLASS_LIST_MACROS_HPP_
#include <class_loader/class_loader.hpp>
/// Register a class with class loader to effectively export it for plugin loading later.
/**
* \def PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
* \param class_type The real class name with namespace qualifier (e.g. Animals::Lion)
* \param base_class_type The real base class type from which class_type inherits
*/
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type) \
CLASS_LOADER_REGISTER_CLASS(class_type, base_class_type)
#endif // PLUGINLIB__CLASS_LIST_MACROS_HPP_

View File

@@ -0,0 +1,37 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Open Source Robotics Foundation, 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 PLUGINLIB__CLASS_LOADER_H_
#define PLUGINLIB__CLASS_LOADER_H_
#include "./class_loader.hpp"
#endif // PLUGINLIB__CLASS_LOADER_H_

View File

@@ -0,0 +1,352 @@
/*
* Copyright (c) 2009, 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 Willow Garage, Inc. 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 PLUGINLIB__CLASS_LOADER_HPP_
#define PLUGINLIB__CLASS_LOADER_HPP_
#include <map>
#include <string>
#include <vector>
#include "boost/algorithm/string.hpp"
#include "class_loader/multi_library_class_loader.hpp"
#include "pluginlib/class_desc.hpp"
#include "pluginlib/class_loader_base.hpp"
#include "pluginlib/exceptions.hpp"
#include "ros/console.h"
#include "ros/package.h"
#include "tinyxml2.h" // NOLINT
// Note: pluginlib has traditionally utilized a "lookup name" for classes that does not match its
// real C++ name.
// This was done due to limitations of how pluginlib was implemented.
// As of version 1.9, a lookup name is no longer necessary and an attempt to the merge two concepts
// is underway.
namespace pluginlib
{
#if __cplusplus >= 201103L
template<typename T>
using UniquePtr = class_loader::ClassLoader::UniquePtr<T>;
#endif
/// A class to help manage and load classes.
template<class T>
class ClassLoader : public ClassLoaderBase
{
public:
typedef typename std::map<std::string, ClassDesc>::iterator ClassMapIterator;
public:
/**
* \param package The package containing the base class
* \param base_class The type of the base class for classes to be loaded
* \param attrib_name The attribute to search for in manifext.xml files, defaults to "plugin"
* \param plugin_xml_paths The list of paths of plugin.xml files, defaults to be crawled via
* ros::package::getPlugins()
* \throws pluginlib::ClassLoaderException if package manifest cannot be found
*/
ClassLoader(
std::string package, std::string base_class,
std::string attrib_name = std::string("plugin"),
std::vector<std::string> plugin_xml_paths = std::vector<std::string>());
~ClassLoader();
/// Create an instance of a desired class, optionally loading the associated library too.
/**
* \param lookup_name The name of the class to load
* \param auto_load Specifies whether or not to automatically load the
* library containing the class, set to true by default.
* \throws pluginlib::LibraryLoadException when the library associated
* with the class cannot be loaded
* \throws pluginlib::CreateClassException when the class cannot be instantiated
* \return An instance of the class
* \deprecated use either createInstance() or createUnmanagedInstance()
*/
[[deprecated]] T * createClassInstance(
const std::string & lookup_name,
bool auto_load = true);
/// Create an instance of a desired class.
/**
* Implicitly calls loadLibraryForClass() to increment the library counter.
*
* Deleting the instance and calling unloadLibraryForClass() is automatically
* handled by the shared pointer.
* \param lookup_name The name of the class to load
* \throws pluginlib::LibraryLoadException when the library associated with
* the class cannot be loaded
* \throws pluginlib::CreateClassException when the class cannot be instantiated
* \return An instance of the class
*/
boost::shared_ptr<T> createInstance(const std::string & lookup_name);
#if __cplusplus >= 201103L
/// Create an instance of a desired class.
/**
* Implicitly calls loadLibraryForClass() to increment the library counter.
*
* Deleting the instance and calling unloadLibraryForClass() is automatically
* handled by the unique pointer.
*
* If you release the wrapped pointer you must manually call the original
* deleter when you want to destroy the released pointer.
*
* \param lookup_name The name of the class to load.
* \throws pluginlib::LibraryLoadException when the library associated with
* the class cannot be loaded.
* \throws pluginlib::CreateClassException when the class cannot be instantiated
* \return An instance of the class
*/
UniquePtr<T> createUniqueInstance(const std::string & lookup_name);
#endif
/// Create an instance of a desired class.
/**
* Implicitly calls loadLibraryForClass() to increment the library counter.
*
* \attention The ownership is transfered to the caller, which is responsible
* for deleting the instance and calling unloadLibraryForClass()
* (in order to decrement the associated library counter and unloading it
* if it is no more used).
* \param lookup_name The name of the class to load
* \throws pluginlib::LibraryLoadException when the library associated with
* the class cannot be loaded
* \throws pluginlib::CreateClassException when the class cannot be instantiated
* \return An instance of the class
*/
T * createUnmanagedInstance(const std::string & lookup_name);
/// Return a list of all available plugin manifest paths for this ClassLoader's base class type.
/**
* \return A vector of strings corresponding to the paths of all available plugin manifests
*/
std::vector<std::string> getPluginXmlPaths();
/// Return a list of all available classes for this ClassLoader's base class type.
/**
* \return A vector of strings corresponding to the names of all available classes
*/
std::vector<std::string> getDeclaredClasses();
/// Strip the package name off of a lookup name.
/**
* \param lookup_name The name of the plugin
* \return The name of the plugin stripped of the package name
*/
virtual std::string getName(const std::string & lookup_name);
/// Given the lookup name of a class, return the type of the associated base class.
/**
* \return The type of the associated base class
*/
virtual std::string getBaseClassType() const;
/// Given the lookup name of a class, return the type of the derived class associated with it.
/**
* \param lookup_name The name of the class
* \return The name of the associated derived class
*/
virtual std::string getClassType(const std::string & lookup_name);
/// Given the lookup name of a class, return its description.
/**
* \param lookup_name The lookup name of the class
* \return The description of the class
*/
virtual std::string getClassDescription(const std::string & lookup_name);
/// Given the name of a class, return the path to its associated library.
/**
* \param lookup_name The name of the class
* \return The path to the associated library
*/
virtual std::string getClassLibraryPath(const std::string & lookup_name);
/// Given the name of a class, return name of the containing package.
/**
* \param lookup_name The name of the class
* \return The name of the containing package
*/
virtual std::string getClassPackage(const std::string & lookup_name);
/// Given the name of a class, return the path of the associated plugin manifest.
/**
* \param lookup_name The name of the class
* \return The path of the associated plugin manifest
*/
virtual std::string getPluginManifestPath(const std::string & lookup_name);
/// Return the libraries that are registered and can be loaded.
/**
* \return A vector of strings corresponding to the names of registered libraries
*/
virtual std::vector<std::string> getRegisteredLibraries();
/// Check if the library for a given class is currently loaded.
/**
* \param lookup_name The lookup name of the class to query
* \return True if the class is loaded, false otherwise
*/
bool isClassLoaded(const std::string & lookup_name);
/// Check if the class associated with a plugin name is available to be loaded.
/**
* \param lookup_name The name of the plugin
* \return true if the plugin is available, false otherwise
*/
virtual bool isClassAvailable(const std::string & lookup_name);
/// Attempt to load the library containing a class with a given name.
/**
* The counter for the library uses (refcount) is also incremented.
*
* \param lookup_name The lookup name of the class to load
* \throws pluginlib::LibraryLoadException if the library for the
* class cannot be loaded
*/
virtual void loadLibraryForClass(const std::string & lookup_name);
/// Refresh the list of all available classes for this ClassLoader's base class type.
/**
* \throws pluginlib::LibraryLoadException if package manifest cannot be found
*/
virtual void refreshDeclaredClasses();
/// Decrement the counter for the library containing a class with a given name.
/**
* Also try to unload the library, If the counter reaches zero.
*
* \param lookup_name The lookup name of the class to unload
* \throws pluginlib::LibraryUnloadException if the library for the
* class cannot be unloaded
* \return The number of pending unloads until the library is removed from memory
*/
virtual int unloadLibraryForClass(const std::string & lookup_name);
private:
/// Return the paths to plugin.xml files.
/**
* \throws pluginlib::LibraryLoadException if package manifest cannot be found
* \return A vector of paths
*/
std::vector<std::string> getPluginXmlPaths(
const std::string & package,
const std::string & attrib_name,
bool force_recrawl = false);
/// Return the available classes.
/**
* \param plugin_xml_paths The vector of paths of plugin.xml files
* \throws pluginlib::LibraryLoadException if package manifest cannot be found
* \return A map of class names and the corresponding descriptions
*/
std::map<std::string, ClassDesc> determineAvailableClasses(
const std::vector<std::string> & plugin_xml_paths);
/// Open a package.xml file and extract the package name (i.e. contents of <name> tag).
/**
* \param package_xml_path The path to the package.xml file
* \return The name of the package if successful, otherwise an empty string
*/
std::string extractPackageNameFromPackageXML(const std::string & package_xml_path);
/// Get a list of paths to try to find a library.
/**
* As we transition from rosbuild to Catkin build systems, plugins can be
* found in the old rosbuild place (pkg_name/lib usually) or somewhere in the
* Catkin build space.
*/
std::vector<std::string> getAllLibraryPathsToTry(
const std::string & library_name,
const std::string & exporting_package_name);
/// Return the paths where libraries are installed according to the Catkin build system.
std::vector<std::string> getCatkinLibraryPaths();
/// Return an error message for an unknown class.
/**
* \param lookup_name The name of the class
* \return The error message
*/
std::string getErrorStringForUnknownClass(const std::string & lookup_name);
/// Get the standard path separator for the native OS (e.g. "/" on *nix, "\" on Windows).
std::string getPathSeparator();
/// Given a package name, return the path where rosbuild thinks plugins are installed.
std::string getROSBuildLibraryPath(const std::string & exporting_package_name);
/// Get the package name from a path to a plugin XML file.
std::string getPackageFromPluginXMLFilePath(const std::string & path);
/// Join two filesystem paths together utilzing appropriate path separator.
std::string joinPaths(const std::string & path1, const std::string & path2);
/// Parse a plugin XML file.
/**
* Also insert the appropriate ClassDesc entries into the passes
* classes_available map.
*/
void processSingleXMLPluginFile(
const std::string & xml_file, std::map<std::string,
ClassDesc> & class_available);
/// Strip all but the filename from an explicit file path.
/**
* \param path The path to strip
* \return The basename of the path
*/
std::string stripAllButFileFromPath(const std::string & path);
/// Helper function for unloading a shared library.
/**
* \param library_path The exact path to the library to unload
* \return The number of pending unloads until the library is removed from memory
*/
int unloadClassLibraryInternal(const std::string & library_path);
private:
std::vector<std::string> plugin_xml_paths_;
// Map from library to class's descriptions described in XML.
std::map<std::string, ClassDesc> classes_available_;
std::string package_;
std::string base_class_;
std::string attrib_name_;
class_loader::MultiLibraryClassLoader lowlevel_class_loader_; // The underlying classloader
};
} // namespace pluginlib
// Note: The implementation of the methods is in a separate file for clarity.
#include "./class_loader_imp.hpp"
#endif // PLUGINLIB__CLASS_LOADER_HPP_

View File

@@ -0,0 +1,37 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Open Source Robotics Foundation, 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 PLUGINLIB__CLASS_LOADER_BASE_H_
#define PLUGINLIB__CLASS_LOADER_BASE_H_
#include "./class_loader_base.hpp"
#endif // PLUGINLIB__CLASS_LOADER_BASE_H_

View File

@@ -0,0 +1,156 @@
/*
* 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 Willow Garage, Inc. 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 PLUGINLIB__CLASS_LOADER_BASE_HPP_
#define PLUGINLIB__CLASS_LOADER_BASE_HPP_
#include <string>
#include <vector>
namespace pluginlib
{
/// Pure virtual base class of pluginlib::ClassLoader which is not templated.
/**
* This allows the writing of non-templated manager code
* which can call all the administrative functions of ClassLoaders -
* everything except createClassInstance(), createInstance()
* and createUnmanagedInstance().
*/
class ClassLoaderBase
{
public:
/// Empty virtual destructor.
virtual ~ClassLoaderBase() {}
/// Return a list of all available plugin manifest paths.
/**
* \return A vector of strings corresponding to the paths of all available plugin manifests
*/
virtual std::vector<std::string> getPluginXmlPaths() = 0;
/// Return a list of all available classes for this ClassLoader's base class type.
/**
* \return A vector of strings corresponding to the names of all available classes
*/
virtual std::vector<std::string> getDeclaredClasses() = 0;
/// Refresh the list of all available classes for this ClassLoader's base class type.
/**
* \throws pluginlib::LibraryLoadException if package manifest cannot be found
*/
virtual void refreshDeclaredClasses() = 0;
/// Strip the package name off of a lookup name.
/**
* \param lookup_name The name of the plugin
* \return The name of the plugin stripped of the package name
*/
virtual std::string getName(const std::string & lookup_name) = 0;
/// Check if the class associated with a plugin name is available to be loaded.
/**
* \param lookup_name The name of the plugin
* \return True if the plugin is available, false otherwise
*/
virtual bool isClassAvailable(const std::string & lookup_name) = 0;
/// Given the lookup name of a class, return the type of the derived class associated with it.
/**
* \param lookup_name The name of the class
* \return The name of the associated derived class
*/
virtual std::string getClassType(const std::string & lookup_name) = 0;
/// Given the lookup name of a class, return its description.
/**
* \param lookup_name The lookup name of the class
* \return The description of the class
*/
virtual std::string getClassDescription(const std::string & lookup_name) = 0;
/// Given the lookup name of a class, return the type of the associated base class.
/**
* \return The type of the associated base class
*/
virtual std::string getBaseClassType() const = 0;
/// Given the name of a class, return name of the containing package.
/**
* \param lookup_name The name of the class
* \return The name of the containing package
*/
virtual std::string getClassPackage(const std::string & lookup_name) = 0;
/// Given the name of a class, return the path of the associated plugin manifest.
/**
* \param lookup_name The name of the class
* \return The path of the associated plugin manifest
*/
virtual std::string getPluginManifestPath(const std::string & lookup_name) = 0;
/// Check if a given class is currently loaded.
/**
* \param lookup_name The lookup name of the class to query
* \return True if the class is loaded, false otherwise
*/
virtual bool isClassLoaded(const std::string & lookup_name) = 0;
/// Attempt to load a class with a given name.
/**
* \param lookup_name The lookup name of the class to load
* \throws pluginlib::LibraryLoadException if the library for the
* class cannot be loaded
*/
virtual void loadLibraryForClass(const std::string & lookup_name) = 0;
/// Attempt to unload a class with a given name.
/**
* \param lookup_name The lookup name of the class to unload
* \throws pluginlib::LibraryUnloadException if the library for the class
* cannot be unloaded
* \return The number of pending unloads until the library is removed from memory
*/
virtual int unloadLibraryForClass(const std::string & lookup_name) = 0;
/// Return the libraries that are registered and can be loaded.
/**
* \return A vector of strings corresponding to the names of registered libraries
*/
virtual std::vector<std::string> getRegisteredLibraries() = 0;
/// Given the name of a class, return the path to its associated library.
/**
* \param lookup_name The name of the class
* \return The path to the associated library
*/
virtual std::string getClassLibraryPath(const std::string & lookup_name) = 0;
};
} // namespace pluginlib
#endif // PLUGINLIB__CLASS_LOADER_BASE_HPP_

View File

@@ -0,0 +1,39 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Open Source Robotics Foundation, 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 PLUGINLIB__CLASS_LOADER_IMP_H_
#define PLUGINLIB__CLASS_LOADER_IMP_H_
// *INDENT-OFF* (prevent uncrustify from adding indention below)
#error Header <pluginlib/class_loader_imp.h> is deprecated, \
but this file should never be included directly, include <pluginlib/class_loader.hpp> instead.
#endif // PLUGINLIB__CLASS_LOADER_IMP_H_

View File

@@ -0,0 +1,836 @@
/*********************************************************************
*
* Software License Agreement (BSD License)
*
* Copyright (c) 2008, 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 Willow Garage, Inc. 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 PLUGINLIB__CLASS_LOADER_IMP_HPP_
#define PLUGINLIB__CLASS_LOADER_IMP_HPP_
#include <cstdlib>
#include <list>
#include <map>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
#include "boost/algorithm/string.hpp"
#include "boost/bind.hpp"
#include "boost/filesystem.hpp"
#include "boost/foreach.hpp"
#include "class_loader/class_loader.hpp"
#include "ros/package.h"
#include "./class_loader.hpp"
#ifdef _WIN32
const std::string os_pathsep(";"); // NOLINT
#else
const std::string os_pathsep(":"); // NOLINT
#endif
namespace pluginlib
{
template<class T>
ClassLoader<T>::ClassLoader(
std::string package, std::string base_class, std::string attrib_name,
std::vector<std::string> plugin_xml_paths)
: plugin_xml_paths_(plugin_xml_paths),
package_(package),
base_class_(base_class),
attrib_name_(attrib_name),
// NOTE: The parameter to the class loader enables/disables on-demand class
// loading/unloading.
// Leaving it off for now... libraries will be loaded immediately and won't
// be unloaded until class loader is destroyed or force unload.
lowlevel_class_loader_(false)
/***************************************************************************/
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Creating ClassLoader, base = %s, address = %p",
base_class.c_str(), this);
if (ros::package::getPath(package_).empty()) {
throw pluginlib::ClassLoaderException("Unable to find package: " + package_);
}
if (0 == plugin_xml_paths_.size()) {
plugin_xml_paths_ = getPluginXmlPaths(package_, attrib_name_);
}
classes_available_ = determineAvailableClasses(plugin_xml_paths_);
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Finished constructring ClassLoader, base = %s, address = %p",
base_class.c_str(), this);
}
template<class T>
ClassLoader<T>::~ClassLoader()
/***************************************************************************/
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Destroying ClassLoader, base = %s, address = %p",
getBaseClassType().c_str(), this);
}
template<class T>
T * ClassLoader<T>::createClassInstance(const std::string & lookup_name, bool auto_load)
/***************************************************************************/
{
// Note: This method is deprecated
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"In deprecated call createClassInstance(), lookup_name = %s, auto_load = %i.",
(lookup_name.c_str()), auto_load);
if (auto_load && !isClassLoaded(lookup_name)) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Autoloading class library before attempting to create instance.");
loadLibraryForClass(lookup_name);
}
try {
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Attempting to create instance through low-level MultiLibraryClassLoader...");
T * obj = lowlevel_class_loader_.createUnmanagedInstance<T>(getClassType(lookup_name));
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Instance created with object pointer = %p", obj);
return obj;
} catch (const class_loader::CreateClassException & ex) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "CreateClassException about to be raised for class %s",
lookup_name.c_str());
throw pluginlib::CreateClassException(ex.what());
}
}
template<class T>
boost::shared_ptr<T> ClassLoader<T>::createInstance(const std::string & lookup_name)
/***************************************************************************/
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Attempting to create managed instance for class %s.",
lookup_name.c_str());
if (!isClassLoaded(lookup_name)) {
loadLibraryForClass(lookup_name);
}
try {
std::string class_type = getClassType(lookup_name);
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "%s maps to real class type %s",
lookup_name.c_str(), class_type.c_str());
boost::shared_ptr<T> obj = lowlevel_class_loader_.createInstance<T>(class_type);
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "boost::shared_ptr to object of real type %s created.",
class_type.c_str());
return obj;
} catch (const class_loader::CreateClassException & ex) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Exception raised by low-level multi-library class loader when attempting "
"to create instance of class %s.",
lookup_name.c_str());
throw pluginlib::CreateClassException(ex.what());
}
}
#if __cplusplus >= 201103L
template<class T>
UniquePtr<T> ClassLoader<T>::createUniqueInstance(const std::string & lookup_name)
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Attempting to create managed (unique) instance for class %s.",
lookup_name.c_str());
if (!isClassLoaded(lookup_name)) {
loadLibraryForClass(lookup_name);
}
try {
std::string class_type = getClassType(lookup_name);
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "%s maps to real class type %s",
lookup_name.c_str(), class_type.c_str());
UniquePtr<T> obj = lowlevel_class_loader_.createUniqueInstance<T>(class_type);
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "std::unique_ptr to object of real type %s created.",
class_type.c_str());
return obj;
} catch (const class_loader::CreateClassException & ex) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Exception raised by low-level multi-library class loader when attempting "
"to create instance of class %s.",
lookup_name.c_str());
throw pluginlib::CreateClassException(ex.what());
}
}
#endif
template<class T>
T * ClassLoader<T>::createUnmanagedInstance(const std::string & lookup_name)
/***************************************************************************/
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Attempting to create UNMANAGED instance for class %s.",
lookup_name.c_str());
if (!isClassLoaded(lookup_name)) {
loadLibraryForClass(lookup_name);
}
T * instance = 0;
try {
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Attempting to create instance through low level multi-library class loader.");
std::string class_type = getClassType(lookup_name);
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "%s maps to real class type %s",
lookup_name.c_str(), class_type.c_str());
instance = lowlevel_class_loader_.createUnmanagedInstance<T>(class_type);
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Instance of type %s created.", class_type.c_str());
} catch (const class_loader::CreateClassException & ex) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Exception raised by low-level multi-library class loader when attempting "
"to create UNMANAGED instance of class %s.",
lookup_name.c_str());
throw pluginlib::CreateClassException(ex.what());
}
return instance;
}
template<class T>
std::vector<std::string> ClassLoader<T>::getPluginXmlPaths(
const std::string & package,
const std::string & attrib_name,
bool force_recrawl)
/***************************************************************************/
{
// Pull possible files from manifests of packages which depend on this package and export class
std::vector<std::string> paths;
ros::package::getPlugins(package, attrib_name, paths, force_recrawl);
return paths;
}
template<class T>
std::map<std::string, ClassDesc> ClassLoader<T>::determineAvailableClasses(
const std::vector<std::string> & plugin_xml_paths)
/***************************************************************************/
{
// mas - This method requires major refactoring...
// not only is it really long and confusing but a lot of the comments do not
// seem to be correct.
// With time I keep correcting small things, but a good rewrite is needed.
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Entering determineAvailableClasses()...");
std::map<std::string, ClassDesc> classes_available;
// Walk the list of all plugin XML files (variable "paths") that are exported by the build system
for (std::vector<std::string>::const_iterator it = plugin_xml_paths.begin();
it != plugin_xml_paths.end(); ++it)
{
try {
processSingleXMLPluginFile(*it, classes_available);
} catch (const pluginlib::InvalidXMLException & e) {
ROS_ERROR_NAMED("pluginlib.ClassLoader",
"Skipped loading plugin with error: %s.",
e.what());
}
}
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Exiting determineAvailableClasses()...");
return classes_available;
}
template<class T>
std::string ClassLoader<T>::extractPackageNameFromPackageXML(const std::string & package_xml_path)
/***************************************************************************/
{
tinyxml2::XMLDocument document;
document.LoadFile(package_xml_path.c_str());
tinyxml2::XMLElement * doc_root_node = document.FirstChildElement("package");
if (NULL == doc_root_node) {
ROS_ERROR_NAMED("pluginlib.ClassLoader",
"Could not find a root element for package manifest at %s.",
package_xml_path.c_str());
return "";
}
assert(document.RootElement() == doc_root_node);
tinyxml2::XMLElement * package_name_node = doc_root_node->FirstChildElement("name");
if (NULL == package_name_node) {
ROS_ERROR_NAMED("pluginlib.ClassLoader",
"package.xml at %s does not have a <name> tag! Cannot determine package "
"which exports plugin.",
package_xml_path.c_str());
return "";
}
const char* package_name_node_txt = package_name_node->GetText();
if (NULL == package_name_node_txt) {
ROS_ERROR_NAMED("pluginlib.ClassLoader",
"package.xml at %s has an invalid <name> tag! Cannot determine package "
"which exports plugin.",
package_xml_path.c_str());
return "";
}
return package_name_node_txt;
}
template<class T>
std::vector<std::string> ClassLoader<T>::getCatkinLibraryPaths()
/***************************************************************************/
{
std::vector<std::string> lib_paths;
const char * env = std::getenv("CMAKE_PREFIX_PATH");
if (env) {
std::string env_catkin_prefix_paths(env);
std::vector<std::string> catkin_prefix_paths;
boost::split(catkin_prefix_paths, env_catkin_prefix_paths, boost::is_any_of(os_pathsep));
BOOST_FOREACH(std::string catkin_prefix_path, catkin_prefix_paths) {
boost::filesystem::path path(catkin_prefix_path);
#ifdef _WIN32
boost::filesystem::path bin("bin");
lib_paths.push_back((path / bin).string());
#endif
boost::filesystem::path lib("lib");
lib_paths.push_back((path / lib).string());
}
}
return lib_paths;
}
template<class T>
std::vector<std::string> ClassLoader<T>::getAllLibraryPathsToTry(
const std::string & library_name,
const std::string & exporting_package_name)
/***************************************************************************/
{
// Catkin-rosbuild Backwards Compatability Rules - Note library_name may be prefixed with
// relative path (e.g. "/lib/libFoo")
// 1. Try catkin library paths (catkin_find --libs) + library_name + extension
// 2. Try catkin library paths
// (catkin_find -- libs) + stripAllButFileFromPath(library_name) + extension
// 3. Try export_pkg/library_name + extension
std::vector<std::string> all_paths;
std::vector<std::string> all_paths_without_extension = getCatkinLibraryPaths();
all_paths_without_extension.push_back(getROSBuildLibraryPath(exporting_package_name));
bool debug_library_suffix = (0 == class_loader::systemLibrarySuffix().compare(0, 1, "d"));
std::string non_debug_suffix;
if (debug_library_suffix) {
non_debug_suffix = class_loader::systemLibrarySuffix().substr(1);
} else {
non_debug_suffix = class_loader::systemLibrarySuffix();
}
std::string library_name_with_extension = library_name + non_debug_suffix;
std::string stripped_library_name = stripAllButFileFromPath(library_name);
std::string stripped_library_name_with_extension = stripped_library_name + non_debug_suffix;
const std::string path_separator = getPathSeparator();
for (unsigned int c = 0; c < all_paths_without_extension.size(); c++) {
std::string current_path = all_paths_without_extension.at(c);
all_paths.push_back(current_path + path_separator + library_name_with_extension);
all_paths.push_back(current_path + path_separator + stripped_library_name_with_extension);
// We're in debug mode, try debug libraries as well
if (debug_library_suffix) {
all_paths.push_back(
current_path + path_separator + library_name + class_loader::systemLibrarySuffix());
all_paths.push_back(
current_path + path_separator + stripped_library_name +
class_loader::systemLibrarySuffix());
}
}
return all_paths;
}
template<class T>
bool ClassLoader<T>::isClassLoaded(const std::string & lookup_name)
/***************************************************************************/
{
return lowlevel_class_loader_.isClassAvailable<T>(getClassType(lookup_name));
}
template<class T>
std::string ClassLoader<T>::getBaseClassType() const
/***************************************************************************/
{
return base_class_;
}
template<class T>
std::string ClassLoader<T>::getClassDescription(const std::string & lookup_name)
/***************************************************************************/
{
ClassMapIterator it = classes_available_.find(lookup_name);
if (it != classes_available_.end()) {
return it->second.description_;
}
return "";
}
template<class T>
std::string ClassLoader<T>::getClassType(const std::string & lookup_name)
/***************************************************************************/
{
ClassMapIterator it = classes_available_.find(lookup_name);
if (it != classes_available_.end()) {
return it->second.derived_class_;
}
return "";
}
template<class T>
std::string ClassLoader<T>::getClassLibraryPath(const std::string & lookup_name)
/***************************************************************************/
{
if (classes_available_.find(lookup_name) == classes_available_.end()) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Class %s has no mapping in classes_available_.",
lookup_name.c_str());
return "";
}
ClassMapIterator it = classes_available_.find(lookup_name);
std::string library_name = it->second.library_name_;
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Class %s maps to library %s in classes_available_.",
lookup_name.c_str(), library_name.c_str());
std::vector<std::string> paths_to_try =
getAllLibraryPathsToTry(library_name, it->second.package_);
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"Iterating through all possible paths where %s could be located...",
library_name.c_str());
for (std::vector<std::string>::const_iterator it = paths_to_try.begin(); it != paths_to_try.end();
it++)
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Checking path %s ", it->c_str());
if (boost::filesystem::exists(*it)) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Library %s found at explicit path %s.",
library_name.c_str(), it->c_str());
return *it;
}
}
return "";
}
template<class T>
std::string ClassLoader<T>::getClassPackage(const std::string & lookup_name)
/***************************************************************************/
{
ClassMapIterator it = classes_available_.find(lookup_name);
if (it != classes_available_.end()) {
return it->second.package_;
}
return "";
}
template<class T>
std::vector<std::string> ClassLoader<T>::getPluginXmlPaths()
/***************************************************************************/
{
return plugin_xml_paths_;
}
template<class T>
std::vector<std::string> ClassLoader<T>::getDeclaredClasses()
/***************************************************************************/
{
std::vector<std::string> lookup_names;
for (ClassMapIterator it = classes_available_.begin(); it != classes_available_.end(); ++it) {
lookup_names.push_back(it->first);
}
return lookup_names;
}
template<class T>
std::string ClassLoader<T>::getErrorStringForUnknownClass(const std::string & lookup_name)
/***************************************************************************/
{
std::string declared_types;
std::vector<std::string> types = getDeclaredClasses();
for (unsigned int i = 0; i < types.size(); i++) {
declared_types = declared_types + std::string(" ") + types[i];
}
return "According to the loaded plugin descriptions the class " + lookup_name +
" with base class type " + base_class_ + " does not exist. Declared types are " +
declared_types;
}
template<class T>
std::string ClassLoader<T>::getName(const std::string & lookup_name)
/***************************************************************************/
{
// remove the package name to get the raw plugin name
std::vector<std::string> split;
boost::split(split, lookup_name, boost::is_any_of("/:"));
return split.back();
}
template<class T>
std::string
ClassLoader<T>::getPackageFromPluginXMLFilePath(const std::string & plugin_xml_file_path)
/***************************************************************************/
{
// Note: This method takes an input a path to a plugin xml file and must determine which
// package the XML file came from. This is not necessariliy the same thing as the member
// variable "package_". The plugin xml file can be located anywhere in the source tree for a
// package
// rosbuild:
// 1. Find nearest encasing manifest.xml
// 2. Once found, the name of the folder containg the manifest should be the
// package name we are looking for
// 3. Confirm package is findable with rospack
// catkin:
// 1. Find nearest encasing package.xml
// 2. Extract name of package from package.xml
std::string package_name;
boost::filesystem::path p(plugin_xml_file_path);
boost::filesystem::path parent = p.parent_path();
// Figure out exactly which package the passed XML file is exported by.
while (true) {
if (boost::filesystem::exists(parent / "package.xml")) {
std::string package_file_path = (boost::filesystem::path(parent / "package.xml")).string();
return extractPackageNameFromPackageXML(package_file_path);
} else if (boost::filesystem::exists(parent / "manifest.xml")) {
#if BOOST_FILESYSTEM_VERSION >= 3
std::string package = parent.filename().string();
#else
std::string package = parent.filename();
#endif
std::string package_path = ros::package::getPath(package);
// package_path is a substr of passed plugin xml path
if (0 == plugin_xml_file_path.find(package_path)) {
package_name = package;
break;
}
}
// Recursive case - hop one folder up
parent = parent.parent_path().string();
// Base case - reached root and cannot find what we're looking for
if (parent.string().empty()) {
return "";
}
}
return package_name;
}
template<class T>
std::string ClassLoader<T>::getPathSeparator()
/***************************************************************************/
{
#if BOOST_FILESYSTEM_VERSION >= 3
# ifdef _WIN32
return boost::filesystem::path("/").string();
# else
return boost::filesystem::path("/").native();
# endif
#else
return boost::filesystem::path("/").external_file_string();
#endif
}
template<class T>
std::string ClassLoader<T>::getPluginManifestPath(const std::string & lookup_name)
/***************************************************************************/
{
ClassMapIterator it = classes_available_.find(lookup_name);
if (it != classes_available_.end()) {
return it->second.plugin_manifest_path_;
}
return "";
}
template<class T>
std::vector<std::string> ClassLoader<T>::getRegisteredLibraries()
/***************************************************************************/
{
return lowlevel_class_loader_.getRegisteredLibraries();
}
template<class T>
std::string ClassLoader<T>::getROSBuildLibraryPath(const std::string & exporting_package_name)
/***************************************************************************/
{
return ros::package::getPath(exporting_package_name);
}
template<class T>
bool ClassLoader<T>::isClassAvailable(const std::string & lookup_name)
/***************************************************************************/
{
return classes_available_.find(lookup_name) != classes_available_.end();
}
template<class T>
std::string ClassLoader<T>::joinPaths(const std::string & path1, const std::string & path2)
/***************************************************************************/
{
boost::filesystem::path p1(path1);
return (p1 / path2).string();
}
template<class T>
void ClassLoader<T>::loadLibraryForClass(const std::string & lookup_name)
/***************************************************************************/
{
ClassMapIterator it = classes_available_.find(lookup_name);
if (it == classes_available_.end()) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Class %s has no mapping in classes_available_.",
lookup_name.c_str());
throw pluginlib::LibraryLoadException(getErrorStringForUnknownClass(lookup_name));
}
std::string library_path = getClassLibraryPath(lookup_name);
if ("" == library_path) {
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "No path could be found to the library containing %s.",
lookup_name.c_str());
std::ostringstream error_msg;
error_msg << "Could not find library corresponding to plugin " << lookup_name <<
". Make sure the plugin description XML file has the correct name of the "
"library and that the library actually exists.";
throw pluginlib::LibraryLoadException(error_msg.str());
}
try {
lowlevel_class_loader_.loadLibrary(library_path);
it->second.resolved_library_path_ = library_path;
} catch (const class_loader::LibraryLoadException & ex) {
std::string error_string =
"Failed to load library " + library_path + ". "
"Make sure that you are calling the PLUGINLIB_EXPORT_CLASS macro in the "
"library code, and that names are consistent between this macro and your XML. "
"Error string: " + ex.what();
throw pluginlib::LibraryLoadException(error_string);
}
}
template<class T>
void ClassLoader<T>::processSingleXMLPluginFile(
const std::string & xml_file, std::map<std::string,
ClassDesc> & classes_available)
/***************************************************************************/
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Processing xml file %s...", xml_file.c_str());
tinyxml2::XMLDocument document;
document.LoadFile(xml_file.c_str());
tinyxml2::XMLElement * config = document.RootElement();
if (NULL == config) {
throw pluginlib::InvalidXMLException(
"XML Document '" + xml_file +
"' has no Root Element. This likely means the XML is malformed or missing.");
return;
}
const char* config_value = config->Value();
if (NULL == config_value) {
throw pluginlib::InvalidXMLException(
"XML Document '" + xml_file +
"' has an invalid Root Element. This likely means the XML is malformed or missing.");
return;
}
if (!(strcmp(config_value, "library") == 0 ||
strcmp(config_value, "class_libraries") == 0))
{
throw pluginlib::InvalidXMLException(
"The XML document '" + xml_file + "' given to add must have either \"library\" or "
"\"class_libraries\" as the root tag");
return;
}
// Step into the filter list if necessary
if (strcmp(config_value, "class_libraries") == 0) {
config = config->FirstChildElement("library");
}
tinyxml2::XMLElement * library = config;
while (library != NULL) {
const char* path = library->Attribute("path");
if (NULL == path) {
ROS_ERROR_NAMED("pluginlib.ClassLoader",
"Attribute 'path' in 'library' tag is missing in %s.", xml_file.c_str());
continue;
}
std::string library_path(path);
if (0 == library_path.size()) {
ROS_ERROR_NAMED("pluginlib.ClassLoader",
"Attribute 'path' in 'library' tag is missing in %s.", xml_file.c_str());
continue;
}
std::string package_name = getPackageFromPluginXMLFilePath(xml_file);
if ("" == package_name) {
ROS_ERROR_NAMED("pluginlib.ClassLoader",
"Could not find package manifest (neither package.xml or deprecated "
"manifest.xml) at same directory level as the plugin XML file %s. "
"Plugins will likely not be exported properly.\n)",
xml_file.c_str());
}
tinyxml2::XMLElement * class_element = library->FirstChildElement("class");
while (class_element) {
std::string derived_class;
if (class_element->Attribute("type") != NULL) {
derived_class = std::string(class_element->Attribute("type"));
} else {
throw pluginlib::ClassLoaderException(
"Class could not be loaded. Attribute 'type' in class tag is missing.");
}
std::string base_class_type;
if (class_element->Attribute("base_class_type") != NULL) {
base_class_type = std::string(class_element->Attribute("base_class_type"));
} else {
throw pluginlib::ClassLoaderException(
"Class could not be loaded. Attribute 'base_class_type' in class tag is missing.");
}
std::string lookup_name;
if (class_element->Attribute("name") != NULL) {
lookup_name = class_element->Attribute("name");
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"XML file specifies lookup name (i.e. magic name) = %s.",
lookup_name.c_str());
} else {
ROS_DEBUG_NAMED("pluginlib.ClassLoader",
"XML file has no lookup name (i.e. magic name) for class %s, "
"assuming lookup_name == real class name.",
derived_class.c_str());
lookup_name = derived_class;
}
// make sure that this class is of the right type before registering it
if (base_class_type == base_class_) {
// register class here
tinyxml2::XMLElement * description = class_element->FirstChildElement("description");
std::string description_str;
if (description) {
description_str = description->GetText() ? description->GetText() : "";
} else {
description_str = "No 'description' tag for this plugin in plugin description file.";
}
classes_available.insert(std::pair<std::string, ClassDesc>(lookup_name,
ClassDesc(lookup_name, derived_class, base_class_type, package_name, description_str,
library_path, xml_file)));
}
// step to next class_element
class_element = class_element->NextSiblingElement("class");
}
library = library->NextSiblingElement("library");
}
}
template<class T>
void ClassLoader<T>::refreshDeclaredClasses()
/***************************************************************************/
{
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Refreshing declared classes.");
// determine classes not currently loaded for removal
std::list<std::string> remove_classes;
for (std::map<std::string, ClassDesc>::const_iterator it = classes_available_.begin();
it != classes_available_.end(); it++)
{
std::string resolved_library_path = it->second.resolved_library_path_;
std::vector<std::string> open_libs = lowlevel_class_loader_.getRegisteredLibraries();
if (std::find(open_libs.begin(), open_libs.end(), resolved_library_path) != open_libs.end()) {
remove_classes.push_back(it->first);
}
}
while (!remove_classes.empty()) {
classes_available_.erase(remove_classes.front());
remove_classes.pop_front();
}
// add new classes
plugin_xml_paths_ = getPluginXmlPaths(package_, attrib_name_, true);
std::map<std::string, ClassDesc> updated_classes = determineAvailableClasses(plugin_xml_paths_);
for (std::map<std::string, ClassDesc>::const_iterator it = updated_classes.begin();
it != updated_classes.end(); it++)
{
if (classes_available_.find(it->first) == classes_available_.end()) {
classes_available_.insert(std::pair<std::string, ClassDesc>(it->first, it->second));
}
}
}
template<class T>
std::string ClassLoader<T>::stripAllButFileFromPath(const std::string & path)
/***************************************************************************/
{
std::string only_file;
size_t c = path.find_last_of(getPathSeparator());
if (std::string::npos == c) {
return path;
} else {
return path.substr(c, path.size());
}
}
template<class T>
int ClassLoader<T>::unloadLibraryForClass(const std::string & lookup_name)
/***************************************************************************/
{
ClassMapIterator it = classes_available_.find(lookup_name);
if (it != classes_available_.end() && it->second.resolved_library_path_ != "UNRESOLVED") {
std::string library_path = it->second.resolved_library_path_;
ROS_DEBUG_NAMED("pluginlib.ClassLoader", "Attempting to unload library %s for class %s",
library_path.c_str(), lookup_name.c_str());
return unloadClassLibraryInternal(library_path);
} else {
throw pluginlib::LibraryUnloadException(getErrorStringForUnknownClass(lookup_name));
}
}
template<class T>
int ClassLoader<T>::unloadClassLibraryInternal(const std::string & library_path)
/***************************************************************************/
{
return lowlevel_class_loader_.unloadLibrary(library_path);
}
} // namespace pluginlib
#endif // PLUGINLIB__CLASS_LOADER_IMP_HPP_

View File

@@ -0,0 +1,107 @@
/*
* 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 Willow Garage, Inc. 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 PLUGINLIB__EXCEPTIONS_HPP_
#define PLUGINLIB__EXCEPTIONS_HPP_
#include <stdexcept>
#include <string>
namespace pluginlib
{
/// A base class for all pluginlib exceptions that inherits from std::runtime_exception.
/**
* \class PluginlibException
*/
class PluginlibException : public std::runtime_error
{
public:
explicit PluginlibException(const std::string & error_desc)
: std::runtime_error(error_desc) {}
};
/// Thrown when pluginlib is unable to load a plugin XML file.
/**
* \class InvalidXMLException
*/
class InvalidXMLException : public PluginlibException
{
public:
explicit InvalidXMLException(const std::string & error_desc)
: PluginlibException(error_desc) {}
};
/// Thrown when pluginlib is unable to load the library associated with a given plugin.
/**
* \class LibraryLoadException
*/
class LibraryLoadException : public PluginlibException
{
public:
explicit LibraryLoadException(const std::string & error_desc)
: PluginlibException(error_desc) {}
};
/// Thrown when pluginlib is unable to instantiate a class loader.
/**
* \class ClassLoaderException
*/
class ClassLoaderException : public PluginlibException
{
public:
explicit ClassLoaderException(const std::string & error_desc)
: PluginlibException(error_desc) {}
};
/// Thrown when pluginlib is unable to unload the library associated with a given plugin.
/**
* \class LibraryUnloadException
*/
class LibraryUnloadException : public PluginlibException
{
public:
explicit LibraryUnloadException(const std::string & error_desc)
: PluginlibException(error_desc) {}
};
/// Thrown when pluginlib is unable to create the class associated with a given plugin.
/**
* \class CreateClassException
*/
class CreateClassException : public PluginlibException
{
public:
explicit CreateClassException(const std::string & error_desc)
: PluginlibException(error_desc) {}
};
} // namespace pluginlib
#endif // PLUGINLIB__EXCEPTIONS_HPP_

View File

@@ -0,0 +1,37 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Open Source Robotics Foundation, 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 PLUGINLIB__PLUGINLIB_EXCEPTIONS_H_
#define PLUGINLIB__PLUGINLIB_EXCEPTIONS_H_
#include "./exceptions.hpp"
#endif // PLUGINLIB__PLUGINLIB_EXCEPTIONS_H_