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
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef PLUGINLIB_CLASS_LOADER_IMP_H_
00040 #define PLUGINLIB_CLASS_LOADER_IMP_H_
00041
00042 #include <cstdlib>
00043 #include <boost/algorithm/string.hpp>
00044 #include <boost/bind.hpp>
00045 #include <boost/filesystem.hpp>
00046 #include <boost/foreach.hpp>
00047 #include <class_loader/class_loader.h>
00048 #include <list>
00049 #include "ros/package.h"
00050 #include <sstream>
00051 #include <stdexcept>
00052
00053 #ifdef _WIN32
00054 const std::string os_pathsep(";");
00055 #else
00056 const std::string os_pathsep(":");
00057 #endif
00058
00059 namespace
00060 {
00061 std::vector<std::string> catkinFindLib() {
00062 std::vector<std::string> lib_paths;
00063 const char* env = std::getenv("CMAKE_PREFIX_PATH");
00064 if (env) {
00065 std::string env_catkin_prefix_paths(env);
00066 std::vector<std::string> catkin_prefix_paths;
00067 boost::split(catkin_prefix_paths, env_catkin_prefix_paths, boost::is_any_of(os_pathsep));
00068 BOOST_FOREACH(std::string catkin_prefix_path, catkin_prefix_paths) {
00069 boost::filesystem::path path(catkin_prefix_path);
00070 boost::filesystem::path lib("lib");
00071 lib_paths.push_back((path / lib).string());
00072 }
00073 }
00074 return lib_paths;
00075 }
00076
00077 }
00078
00079 namespace pluginlib
00080 {
00081 template <class T>
00082 ClassLoader<T>::ClassLoader(std::string package, std::string base_class, std::string attrib_name, std::vector<std::string> plugin_xml_paths) :
00083 plugin_xml_paths_(plugin_xml_paths),
00084 package_(package),
00085 base_class_(base_class),
00086 attrib_name_(attrib_name),
00087 lowlevel_class_loader_(false)
00088
00089 {
00090 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Creating ClassLoader, base = %s, address = %p", base_class.c_str(), this);
00091 if (ros::package::getPath(package_).empty())
00092 {
00093 throw pluginlib::ClassLoaderException("Unable to find package: " + package_);
00094 }
00095
00096 if (plugin_xml_paths_.size() == 0)
00097 {
00098 plugin_xml_paths_ = getPluginXmlPaths(package_, attrib_name_);
00099 }
00100 classes_available_ = determineAvailableClasses(plugin_xml_paths_);
00101 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Finished constructring ClassLoader, base = %s, address = %p", base_class.c_str(), this);
00102 }
00103
00104 template <class T>
00105 ClassLoader<T>::~ClassLoader()
00106
00107 {
00108 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Destroying ClassLoader, base = %s, address = %p", getBaseClassType().c_str(), this);
00109 }
00110
00111
00112 template <class T>
00113 T* ClassLoader<T>::createClassInstance(const std::string& lookup_name, bool auto_load)
00114
00115 {
00116
00117 ROS_DEBUG_NAMED("pluginlib.ClassLoader","In deprecated call createClassInstance(), lookup_name = %s, auto_load = %i.", (lookup_name.c_str()), auto_load);
00118
00119 if (auto_load && !isClassLoaded(lookup_name))
00120 {
00121 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Autoloading class library before attempting to create instance.");
00122 loadLibraryForClass(lookup_name);
00123 }
00124
00125 try
00126 {
00127 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Attempting to create instance through low-level MultiLibraryClassLoader...");
00128 T* obj = lowlevel_class_loader_.createUnmanagedInstance<T>(getClassType(lookup_name));
00129 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Instance created with object pointer = %p", obj);
00130
00131 return obj;
00132 }
00133 catch (const class_loader::CreateClassException& ex)
00134 {
00135 ROS_DEBUG_NAMED("pluginlib.ClassLoader","CreateClassException about to be raised for class %s", lookup_name.c_str());
00136 throw pluginlib::CreateClassException(ex.what());
00137 }
00138 }
00139
00140 template <class T>
00141 boost::shared_ptr<T> ClassLoader<T>::createInstance(const std::string& lookup_name)
00142
00143 {
00144 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Attempting to create managed instance for class %s.", lookup_name.c_str());
00145
00146 if (!isClassLoaded(lookup_name))
00147 loadLibraryForClass(lookup_name);
00148
00149 try
00150 {
00151 std::string class_type = getClassType(lookup_name);
00152 ROS_DEBUG_NAMED("pluginlib.ClassLoader","%s maps to real class type %s", lookup_name.c_str(), class_type.c_str());
00153
00154 boost::shared_ptr<T> obj = lowlevel_class_loader_.createInstance<T>(class_type);
00155
00156 ROS_DEBUG_NAMED("pluginlib.ClassLoader","boost::shared_ptr to object of real type %s created.", class_type.c_str());
00157
00158 return obj;
00159 }
00160 catch (const class_loader::CreateClassException& ex)
00161 {
00162 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());
00163 throw pluginlib::CreateClassException(ex.what());
00164 }
00165 }
00166
00167 #if __cplusplus >= 201103L
00168 template <class T>
00169 UniquePtr<T> ClassLoader<T>::createUniqueInstance(const std::string& lookup_name)
00170 {
00171 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Attempting to create managed (unique) instance for class %s.", lookup_name.c_str());
00172
00173 if (!isClassLoaded(lookup_name))
00174 loadLibraryForClass(lookup_name);
00175
00176 try
00177 {
00178 std::string class_type = getClassType(lookup_name);
00179 ROS_DEBUG_NAMED("pluginlib.ClassLoader","%s maps to real class type %s", lookup_name.c_str(), class_type.c_str());
00180
00181 UniquePtr<T> obj = lowlevel_class_loader_.createUniqueInstance<T>(class_type);
00182
00183 ROS_DEBUG_NAMED("pluginlib.ClassLoader","std::unique_ptr to object of real type %s created.", class_type.c_str());
00184
00185 return obj;
00186 }
00187 catch (const class_loader::CreateClassException& ex)
00188 {
00189 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());
00190 throw pluginlib::CreateClassException(ex.what());
00191 }
00192
00193 }
00194 #endif
00195
00196 template <class T>
00197 T* ClassLoader<T>::createUnmanagedInstance(const std::string& lookup_name)
00198
00199 {
00200 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Attempting to create UNMANAGED instance for class %s.", lookup_name.c_str());
00201
00202 if (!isClassLoaded(lookup_name))
00203 loadLibraryForClass(lookup_name);
00204
00205 T* instance = 0;
00206 try
00207 {
00208 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Attempting to create instance through low level multi-library class loader.");
00209 std::string class_type = getClassType(lookup_name);
00210 ROS_DEBUG_NAMED("pluginlib.ClassLoader","%s maps to real class type %s", lookup_name.c_str(), class_type.c_str());
00211 instance = lowlevel_class_loader_.createUnmanagedInstance<T>(class_type);
00212 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Instance of type %s created.", class_type.c_str());
00213 }
00214 catch (const class_loader::CreateClassException& ex)
00215 {
00216 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());
00217 throw pluginlib::CreateClassException(ex.what());
00218 }
00219 return instance;
00220 }
00221
00222 template <class T>
00223 std::vector<std::string> ClassLoader<T>::getPluginXmlPaths(const std::string& package, const std::string& attrib_name, bool force_recrawl)
00224
00225 {
00226
00227 std::vector<std::string> paths;
00228 ros::package::getPlugins(package, attrib_name, paths, force_recrawl);
00229 return paths;
00230 }
00231
00232 template <class T>
00233 std::map<std::string, ClassDesc> ClassLoader<T>::determineAvailableClasses(const std::vector<std::string>& plugin_xml_paths)
00234
00235 {
00236
00237
00238 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Entering determineAvailableClasses()...");
00239 std::map<std::string, ClassDesc> classes_available;
00240
00241
00242 for (std::vector<std::string>::const_iterator it = plugin_xml_paths.begin(); it != plugin_xml_paths.end(); ++it)
00243 {
00244 processSingleXMLPluginFile(*it, classes_available);
00245 }
00246
00247 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Exiting determineAvailableClasses()...");
00248 return classes_available;
00249 }
00250
00251 template <class T>
00252 std::string ClassLoader<T>::extractPackageNameFromPackageXML(const std::string& package_xml_path)
00253
00254 {
00255 TiXmlDocument document;
00256 document.LoadFile(package_xml_path);
00257 TiXmlElement* doc_root_node = document.FirstChildElement("package");
00258 if (doc_root_node == NULL)
00259 {
00260 ROS_ERROR_NAMED("pluginlib.ClassLoader","Could not find a root element for package manifest at %s.", package_xml_path.c_str());
00261 return "";
00262 }
00263
00264 assert(doc_root_node == document.RootElement());
00265
00266 TiXmlElement* package_name_node = doc_root_node->FirstChildElement("name");
00267 if(package_name_node == NULL)
00268 {
00269 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());
00270 return "";
00271 }
00272
00273 return(package_name_node->GetText());
00274 }
00275
00276 template <class T>
00277 std::vector<std::string> ClassLoader<T>::getCatkinLibraryPaths()
00278
00279 {
00280 return(catkinFindLib());
00281 }
00282
00283 template <class T>
00284 std::vector<std::string> ClassLoader<T>::getAllLibraryPathsToTry(const std::string& library_name, const std::string& exporting_package_name)
00285
00286 {
00287
00288
00289
00290
00291
00292 std::vector<std::string> all_paths;
00293 std::vector<std::string> all_paths_without_extension = getCatkinLibraryPaths();
00294 all_paths_without_extension.push_back(getROSBuildLibraryPath(exporting_package_name));
00295 bool debug_library_suffix = (class_loader::systemLibrarySuffix().compare(0, 1, "d") == 0);
00296 std::string non_debug_suffix;
00297 if(debug_library_suffix) {
00298 non_debug_suffix = class_loader::systemLibrarySuffix().substr(1);
00299 } else {
00300 non_debug_suffix = class_loader::systemLibrarySuffix();
00301 }
00302 std::string library_name_with_extension = library_name + non_debug_suffix;
00303 std::string stripped_library_name = stripAllButFileFromPath(library_name);
00304 std::string stripped_library_name_with_extension = stripped_library_name + non_debug_suffix;
00305
00306 const std::string path_separator = getPathSeparator();
00307
00308 for(unsigned int c = 0; c < all_paths_without_extension.size(); c++)
00309 {
00310 std::string current_path = all_paths_without_extension.at(c);
00311 all_paths.push_back(current_path + path_separator + library_name_with_extension);
00312 all_paths.push_back(current_path + path_separator + stripped_library_name_with_extension);
00313
00314 if(debug_library_suffix) {
00315 all_paths.push_back(current_path + path_separator + library_name + class_loader::systemLibrarySuffix());
00316 all_paths.push_back(current_path + path_separator + stripped_library_name + class_loader::systemLibrarySuffix());
00317 }
00318 }
00319
00320 return(all_paths);
00321 }
00322
00323 template <class T>
00324 bool ClassLoader<T>::isClassLoaded(const std::string& lookup_name)
00325
00326 {
00327 return lowlevel_class_loader_.isClassAvailable<T>(getClassType(lookup_name));
00328 }
00329
00330 template <class T>
00331 std::string ClassLoader<T>::getBaseClassType() const
00332
00333 {
00334 return base_class_;
00335 }
00336
00337 template <class T>
00338 std::string ClassLoader<T>::getClassDescription(const std::string& lookup_name)
00339
00340 {
00341 ClassMapIterator it = classes_available_.find(lookup_name);
00342 if (it != classes_available_.end())
00343 return it->second.description_;
00344 return "";
00345 }
00346
00347 template <class T>
00348 std::string ClassLoader<T>::getClassType(const std::string& lookup_name)
00349
00350 {
00351 ClassMapIterator it = classes_available_.find(lookup_name);
00352 if (it != classes_available_.end())
00353 return it->second.derived_class_;
00354 return "";
00355 }
00356
00357 template <class T>
00358 std::string ClassLoader<T>::getClassLibraryPath(const std::string& lookup_name)
00359
00360 {
00361 if (classes_available_.find(lookup_name) == classes_available_.end())
00362 {
00363 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Class %s has no mapping in classes_available_.", lookup_name.c_str());
00364 return "";
00365 }
00366 ClassMapIterator it = classes_available_.find(lookup_name);
00367 std::string library_name = it->second.library_name_;
00368 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Class %s maps to library %s in classes_available_.", lookup_name.c_str(), library_name.c_str());
00369
00370 std::vector<std::string> paths_to_try = getAllLibraryPathsToTry(library_name, it->second.package_);
00371
00372 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Iterating through all possible paths where %s could be located...", library_name.c_str());
00373 for(std::vector<std::string>::const_iterator it = paths_to_try.begin(); it != paths_to_try.end(); it++)
00374 {
00375 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Checking path %s ", it->c_str());
00376 if (boost::filesystem::exists(*it))
00377 {
00378 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Library %s found at explicit path %s.", library_name.c_str(), it->c_str());
00379 return *it;
00380 }
00381 }
00382 return "";
00383 }
00384
00385 template <class T>
00386 std::string ClassLoader<T>::getClassPackage(const std::string& lookup_name)
00387
00388 {
00389 ClassMapIterator it = classes_available_.find(lookup_name);
00390 if (it != classes_available_.end())
00391 return it->second.package_;
00392 return "";
00393 }
00394
00395 template <class T>
00396 std::vector<std::string> ClassLoader<T>::getPluginXmlPaths()
00397
00398 {
00399 return plugin_xml_paths_;
00400 }
00401
00402 template <class T>
00403 std::vector<std::string> ClassLoader<T>::getDeclaredClasses()
00404
00405 {
00406 std::vector<std::string> lookup_names;
00407 for (ClassMapIterator it = classes_available_.begin(); it != classes_available_.end(); ++it)
00408 lookup_names.push_back(it->first);
00409
00410 return lookup_names;
00411 }
00412
00413 template <class T>
00414 std::string ClassLoader<T>::getErrorStringForUnknownClass(const std::string& lookup_name)
00415
00416 {
00417 std::string declared_types;
00418 std::vector<std::string> types = getDeclaredClasses();
00419 for ( unsigned int i = 0; i < types.size(); i ++)
00420 {
00421 declared_types = declared_types + std::string(" ") + types[i];
00422 }
00423 return "According to the loaded plugin descriptions the class " + lookup_name
00424 + " with base class type " + base_class_ + " does not exist. Declared types are " + declared_types;
00425 }
00426
00427 template <class T>
00428 std::string ClassLoader<T>::getName(const std::string& lookup_name)
00429
00430 {
00431
00432 std::vector<std::string> split;
00433 boost::split(split, lookup_name, boost::is_any_of("/:"));
00434 return split.back();
00435 }
00436
00437 template <class T>
00438 std::string ClassLoader<T>::getPackageFromPluginXMLFilePath(const std::string & plugin_xml_file_path)
00439
00440 {
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 std::string package_name;
00456 boost::filesystem::path p(plugin_xml_file_path);
00457 boost::filesystem::path parent = p.parent_path();
00458
00459
00460 while (true)
00461 {
00462 if(boost::filesystem::exists(parent / "package.xml"))
00463 {
00464 std::string package_file_path = (boost::filesystem::path(parent / "package.xml")).string();
00465 return(extractPackageNameFromPackageXML(package_file_path));
00466 }
00467 else if (boost::filesystem::exists(parent / "manifest.xml"))
00468 {
00469 #if BOOST_FILESYSTEM_VERSION >= 3
00470 std::string package = parent.filename().string();
00471 #else
00472 std::string package = parent.filename();
00473 #endif
00474 std::string package_path = ros::package::getPath(package);
00475
00476 if (plugin_xml_file_path.find(package_path) == 0)
00477 {
00478 package_name = package;
00479 break;
00480 }
00481 }
00482
00483
00484 parent = parent.parent_path().string();
00485
00486
00487 if (parent.string().empty())
00488 return "";
00489 }
00490
00491 return package_name;
00492 }
00493
00494 template <class T>
00495 std::string ClassLoader<T>::getPathSeparator()
00496
00497 {
00498 #if BOOST_FILESYSTEM_VERSION >= 3
00499 return(boost::filesystem::path("/").native());
00500 #else
00501 return(boost::filesystem::path("/").external_file_string());
00502 #endif
00503 }
00504
00505
00506 template <class T>
00507 std::string ClassLoader<T>::getPluginManifestPath(const std::string& lookup_name)
00508
00509 {
00510 ClassMapIterator it = classes_available_.find(lookup_name);
00511 if (it != classes_available_.end())
00512 return it->second.plugin_manifest_path_;
00513 return "";
00514 }
00515
00516
00517 template <class T>
00518 std::vector<std::string> ClassLoader<T>::getRegisteredLibraries()
00519
00520 {
00521 return(lowlevel_class_loader_.getRegisteredLibraries());
00522 }
00523
00524 template <class T>
00525 std::string ClassLoader<T>::getROSBuildLibraryPath(const std::string& exporting_package_name)
00526
00527 {
00528 return(ros::package::getPath(exporting_package_name));
00529 }
00530
00531 template <class T>
00532 bool ClassLoader<T>::isClassAvailable(const std::string& lookup_name)
00533
00534 {
00535 return classes_available_.find(lookup_name) != classes_available_.end();
00536 }
00537
00538 template <class T>
00539 std::string ClassLoader<T>::joinPaths(const std::string& path1, const std::string& path2)
00540
00541 {
00542 boost::filesystem::path p1(path1);
00543 return (p1 / path2).string();
00544 }
00545
00546 template <class T>
00547 void ClassLoader<T>::loadLibraryForClass(const std::string& lookup_name)
00548
00549 {
00550 ClassMapIterator it = classes_available_.find(lookup_name);
00551 if (it == classes_available_.end())
00552 {
00553 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Class %s has no mapping in classes_available_.", lookup_name.c_str());
00554 throw pluginlib::LibraryLoadException(getErrorStringForUnknownClass(lookup_name));
00555 }
00556
00557 std::string library_path = getClassLibraryPath(lookup_name);
00558 if (library_path == "")
00559 {
00560 ROS_DEBUG_NAMED("pluginlib.ClassLoader","No path could be found to the library containing %s.", lookup_name.c_str());
00561 std::ostringstream error_msg;
00562 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.";
00563 throw pluginlib::LibraryLoadException(error_msg.str());
00564 }
00565
00566 try
00567 {
00568 lowlevel_class_loader_.loadLibrary(library_path);
00569 it->second.resolved_library_path_ = library_path;
00570 }
00571 catch(const class_loader::LibraryLoadException& ex)
00572 {
00573 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();
00574 throw pluginlib::LibraryLoadException(error_string);
00575 }
00576 }
00577
00578 template <class T>
00579 void ClassLoader<T>::processSingleXMLPluginFile(const std::string& xml_file, std::map<std::string, ClassDesc>& classes_available)
00580
00581 {
00582 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Processing xml file %s...", xml_file.c_str());
00583 TiXmlDocument document;
00584 document.LoadFile(xml_file);
00585 TiXmlElement * config = document.RootElement();
00586 if (config == NULL)
00587 {
00588 ROS_ERROR_NAMED("pluginlib.ClassLoader","Skipping XML Document \"%s\" which had no Root Element. This likely means the XML is malformed or missing.", xml_file.c_str());
00589 return;
00590 }
00591 if (config->ValueStr() != "library" &&
00592 config->ValueStr() != "class_libraries")
00593 {
00594 ROS_ERROR_NAMED("pluginlib.ClassLoader","The XML document \"%s\" given to add must have either \"library\" or \
00595 \"class_libraries\" as the root tag", xml_file.c_str());
00596 return;
00597 }
00598
00599 if (config->ValueStr() == "class_libraries")
00600 {
00601 config = config->FirstChildElement("library");
00602 }
00603
00604 TiXmlElement* library = config;
00605 while ( library != NULL)
00606 {
00607 std::string library_path = library->Attribute("path");
00608 if (library_path.size() == 0)
00609 {
00610 ROS_ERROR_NAMED("pluginlib.ClassLoader","Failed to find Path Attirbute in library element in %s", xml_file.c_str());
00611 continue;
00612 }
00613
00614 std::string package_name = getPackageFromPluginXMLFilePath(xml_file);
00615 if (package_name == "")
00616 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());
00617
00618 TiXmlElement* class_element = library->FirstChildElement("class");
00619 while (class_element)
00620 {
00621 std::string derived_class;
00622 if (class_element->Attribute("type") != NULL) {
00623 derived_class = std::string(class_element->Attribute("type"));
00624 } else {
00625 throw pluginlib::ClassLoaderException("Class could not be loaded. Attribute 'type' in class tag is missing.");
00626 }
00627
00628 std::string base_class_type;
00629 if (class_element->Attribute("base_class_type") != NULL) {
00630 base_class_type = std::string(class_element->Attribute("base_class_type"));
00631 } else {
00632 throw pluginlib::ClassLoaderException("Class could not be loaded. Attribute 'base_class_type' in class tag is missing.");
00633 }
00634
00635 std::string lookup_name;
00636 if(class_element->Attribute("name") != NULL)
00637 {
00638 lookup_name = class_element->Attribute("name");
00639 ROS_DEBUG_NAMED("pluginlib.ClassLoader","XML file specifies lookup name (i.e. magic name) = %s.", lookup_name.c_str());
00640 }
00641 else
00642 {
00643 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());
00644 lookup_name = derived_class;
00645 }
00646
00647
00648 if(base_class_type == base_class_){
00649
00650
00651 TiXmlElement* description = class_element->FirstChildElement("description");
00652 std::string description_str;
00653 if (description)
00654 description_str = description->GetText() ? description->GetText() : "";
00655 else
00656 description_str = "No 'description' tag for this plugin in plugin description file.";
00657
00658 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)));
00659 }
00660
00661
00662 class_element = class_element->NextSiblingElement( "class" );
00663 }
00664 library = library->NextSiblingElement( "library" );
00665 }
00666 }
00667
00668 template <class T>
00669 void ClassLoader<T>::refreshDeclaredClasses()
00670
00671 {
00672 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Refreshing declared classes.");
00673
00674 std::list<std::string> remove_classes;
00675 for (std::map<std::string, ClassDesc>::const_iterator it = classes_available_.begin(); it != classes_available_.end(); it++)
00676 {
00677
00678 std::string resolved_library_path = it->second.resolved_library_path_;
00679 std::vector<std::string> open_libs = lowlevel_class_loader_.getRegisteredLibraries();
00680 if(std::find(open_libs.begin(), open_libs.end(), resolved_library_path) != open_libs.end())
00681 remove_classes.push_back(it->first);
00682 }
00683
00684 while (!remove_classes.empty())
00685 {
00686 classes_available_.erase(remove_classes.front());
00687 remove_classes.pop_front();
00688 }
00689
00690
00691 plugin_xml_paths_ = getPluginXmlPaths(package_, attrib_name_, true);
00692 std::map<std::string, ClassDesc> updated_classes = determineAvailableClasses(plugin_xml_paths_);
00693 for (std::map<std::string, ClassDesc>::const_iterator it = updated_classes.begin(); it != updated_classes.end(); it++)
00694 {
00695 if (classes_available_.find(it->first) == classes_available_.end())
00696 classes_available_.insert(std::pair<std::string, ClassDesc>(it->first, it->second));
00697 }
00698 }
00699
00700 template <class T>
00701 std::string ClassLoader<T>::stripAllButFileFromPath(const std::string& path)
00702
00703 {
00704 std::string only_file;
00705 size_t c = path.find_last_of(getPathSeparator());
00706 if(c == std::string::npos)
00707 return(path);
00708 else
00709 return(path.substr(c, path.size()));
00710 }
00711
00712 template <class T>
00713 int ClassLoader<T>::unloadLibraryForClass(const std::string& lookup_name)
00714
00715 {
00716 ClassMapIterator it = classes_available_.find(lookup_name);
00717 if (it != classes_available_.end() && it->second.resolved_library_path_ != "UNRESOLVED")
00718 {
00719 std::string library_path = it->second.resolved_library_path_;
00720 ROS_DEBUG_NAMED("pluginlib.ClassLoader","Attempting to unload library %s for class %s", library_path.c_str(), lookup_name.c_str());
00721 return unloadClassLibraryInternal(library_path);
00722 }
00723 else
00724 {
00725 throw pluginlib::LibraryUnloadException(getErrorStringForUnknownClass(lookup_name));
00726 }
00727 }
00728
00729 template <class T>
00730 int ClassLoader<T>::unloadClassLibraryInternal(const std::string& library_path)
00731
00732 {
00733 return(lowlevel_class_loader_.unloadLibrary(library_path));
00734 }
00735
00736 }
00737
00738
00739
00740
00741 #endif