7 #include "fwRuntime/io/BundleDescriptorReader.hpp" 9 #include "fwRuntime/Bundle.hpp" 10 #include "fwRuntime/ConfigurationElement.hpp" 11 #include "fwRuntime/dl/Library.hpp" 12 #include "fwRuntime/Extension.hpp" 13 #include "fwRuntime/ExtensionPoint.hpp" 14 #include "fwRuntime/io/Validator.hpp" 15 #include "fwRuntime/operations.hpp" 17 #include <boost/filesystem/operations.hpp> 18 #include <boost/filesystem/path.hpp> 20 #include <libxml/parser.h> 21 #include <libxml/xinclude.h> 32 std::string BundleDescriptorReader::CLASS(
"class");
33 std::string BundleDescriptorReader::EXTENSION(
"extension");
34 std::string BundleDescriptorReader::EXTENSION_POINT(
"extension-point");
35 std::string BundleDescriptorReader::ID(
"id");
36 std::string BundleDescriptorReader::IMPLEMENTS(
"implements");
37 std::string BundleDescriptorReader::LIBRARY(
"library");
38 std::string BundleDescriptorReader::NAME(
"name");
39 std::string BundleDescriptorReader::PLUGIN(
"plugin");
40 std::string BundleDescriptorReader::REQUIREMENT(
"requirement");
41 std::string BundleDescriptorReader::SCHEMA(
"schema");
42 std::string BundleDescriptorReader::VERSION(
"version");
43 std::string BundleDescriptorReader::POINT(
"point");
48 const ::boost::filesystem::path& location)
51 ::boost::filesystem::path normalizedPath(location);
52 normalizedPath.normalize();
55 if(::boost::filesystem::exists(normalizedPath) ==
false ||
56 ::boost::filesystem::is_directory(normalizedPath) ==
false)
58 throw RuntimeException(
"'" + normalizedPath.string() +
"': not a directory.");
62 BundleContainer bundles;
63 ::boost::filesystem::directory_iterator currentEntry(normalizedPath);
64 ::boost::filesystem::directory_iterator endEntry;
65 for(; currentEntry != endEntry; ++currentEntry)
67 ::boost::filesystem::path entryPath = *currentEntry;
69 if(::boost::filesystem::is_directory(entryPath))
76 bundles.push_back( bundle );
81 OSLM_INFO(
"'"<< entryPath.string() <<
"': skipped. " << runtimeException.what() );
83 catch(const ::fwCore::Exception& exception)
85 OSLM_INFO(
"'"<< entryPath.string() <<
"': skipped. " << exception.what() );
96 std::shared_ptr<Bundle> bundle;
98 ::boost::filesystem::path descriptorLocation(location /
"plugin.xml");
99 if(::boost::filesystem::exists(descriptorLocation) ==
false)
101 throw ::fwCore::Exception(std::string(
"'plugin.xml': file not found in ") + location.string());
105 auto pluginXSDLocation = ::fwRuntime::getLibraryResourceFilePath(
"fwRuntime-" FWRUNTIME_VER
"/plugin.xsd");
108 if( validator.
validate(descriptorLocation) == false )
114 xmlDocPtr document = xmlParseFile( descriptorLocation.string().c_str() );
123 xmlNodePtr rootNode = xmlDocGetRootElement(document);
125 if (xmlXIncludeProcessTreeFlags(rootNode, XML_PARSE_NOBASEFIX) == -1)
130 if(xmlStrcmp(rootNode->name, (
const xmlChar*) PLUGIN.c_str()) != 0)
137 ::boost::filesystem::path completeLocation(location);
139 if(!completeLocation.is_complete())
144 bundle = processPlugin(rootNode, completeLocation);
147 xmlFreeDoc(document);
149 catch(std::exception& exception)
151 xmlFreeDoc(document);
160 const std::shared_ptr<Bundle> bundle)
165 std::string name((
const char*) node->name);
170 for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
172 std::string name((
const char*) curAttr->name);
173 std::string value((
const char*) curAttr->children->content);
175 configurationElement->setAttributeValue(name, value);
179 xmlNodePtr curChild = node->children;
180 for(curChild = node->children; curChild != 0; curChild = curChild->next)
182 if(curChild->type == XML_TEXT_NODE && !xmlIsBlankNode(curChild))
184 std::string value((
const char*) curChild->content);
187 "Bundle : " << ( bundle ? bundle->getIdentifier() :
"<None>" ) <<
", node: " << name <<
", blanks in xml nodes can result in unexpected behaviour. Consider using <![CDATA[ ... ]]>.",
188 (value.find(
"\n") != std::string::npos || value.find(
"\t") != std::string::npos));
190 configurationElement->setValue( configurationElement->getValue() + value );
193 else if(curChild->type == XML_CDATA_SECTION_NODE )
195 std::string value((
const char*) curChild->content);
196 configurationElement->setValue( configurationElement->getValue() + value );
200 else if(curChild->type == XML_ELEMENT_NODE)
203 configurationElement->addConfigurationElement(element);
209 return configurationElement;
214 std::shared_ptr<Extension> BundleDescriptorReader::processExtension(xmlNodePtr node,
215 const std::shared_ptr<Bundle> bundle)
220 std::string identifier;
221 for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
223 if(xmlStrcmp(curAttr->name, (
const xmlChar*) ID.c_str()) == 0)
225 identifier = (
const char*) curAttr->children->content;
229 if(xmlStrcmp(curAttr->name, (
const xmlChar*) IMPLEMENTS.c_str()) == 0)
231 point = (
const char*) curAttr->children->content;
237 std::shared_ptr<Extension> extension(
new Extension(bundle, identifier, point, node));
241 for(curChild = node->children; curChild != 0; curChild = curChild->next)
243 if(curChild->type == XML_ELEMENT_NODE)
246 extension->addConfigurationElement(element);
257 const std::shared_ptr<Bundle> bundle)
262 std::string identifier;
263 for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
265 if(xmlStrcmp(curAttr->name, (
const xmlChar*) ID.c_str()) == 0)
267 identifier = (
const char*) curAttr->children->content;
271 if(xmlStrcmp(curAttr->name, (
const xmlChar*) SCHEMA.c_str()) == 0)
273 schema = (
const char*) curAttr->children->content;
277 std::shared_ptr<ExtensionPoint> extensionPoint(
new ExtensionPoint(bundle, identifier, schema));
280 std::vector< std::shared_ptr<Extension> > extensionContainer;
282 for(curChild = node->children; curChild != 0; curChild = curChild->next)
284 if(curChild->type == XML_ELEMENT_NODE)
286 if( xmlStrcmp(curChild->name, (
const xmlChar*) IMPLEMENTS.c_str()) == 0 )
288 std::string extensionId = (
const char*) curChild->children->content;
289 std::shared_ptr<Extension> extension(
new Extension(bundle, identifier, extensionId, curChild));
290 extensionContainer.push_back( extension );
300 std::shared_ptr<ExtensionPoint> BundleDescriptorReader::processExtensionPoint(xmlNodePtr node,
301 const std::shared_ptr<Bundle> bundle)
306 std::string identifier;
308 for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
310 if(xmlStrcmp(curAttr->name, (
const xmlChar*) ID.c_str()) == 0)
312 identifier = (
const char*) curAttr->children->content;
316 if(xmlStrcmp(curAttr->name, (
const xmlChar*) SCHEMA.c_str()) == 0)
318 schema = (
const char*) curAttr->children->content;
331 std::shared_ptr<dl::Library> BundleDescriptorReader::processLibrary(xmlNodePtr node)
336 for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
338 if(xmlStrcmp(curAttr->name, (
const xmlChar*) NAME.c_str()) == 0)
340 name = (
const char*) curAttr->children->content;
346 std::shared_ptr<dl::Library> library(
new dl::Library(name) );
352 std::shared_ptr<Bundle> BundleDescriptorReader::processPlugin(xmlNodePtr node,
353 const ::boost::filesystem::path& location)
356 std::shared_ptr<Bundle> bundle;
359 std::string bundleIdentifier;
361 std::string pluginClass;
362 for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
364 if(xmlStrcmp(curAttr->name, (
const xmlChar*) ID.c_str()) == 0)
366 bundleIdentifier = (
const char*) curAttr->children->content;
370 if(xmlStrcmp(curAttr->name, (
const xmlChar*) CLASS.c_str()) == 0)
372 pluginClass = (
const char*) curAttr->children->content;
376 if(xmlStrcmp(curAttr->name, (
const xmlChar*) VERSION.c_str()) == 0)
378 version = (
const char*) curAttr->children->content;
382 SLM_ASSERT(
"bundle identifier is empty", !bundleIdentifier.empty());
388 if(pluginClass.empty() ==
true)
390 bundle = std::shared_ptr<Bundle>(
new Bundle(location, bundleIdentifier, version) );
394 bundle = std::shared_ptr<Bundle>(
new Bundle(location, bundleIdentifier, version, pluginClass) );
399 for(curChild = node->children; curChild != 0; curChild = curChild->next)
402 if(curChild->type != XML_ELEMENT_NODE)
408 if(xmlStrcmp(curChild->name, (
const xmlChar*) EXTENSION.c_str()) == 0)
410 std::shared_ptr<Extension> extension(processExtension(curChild, bundle));
411 bundle->addExtension(extension);
416 if(xmlStrcmp(curChild->name, (
const xmlChar*) EXTENSION_POINT.c_str()) == 0)
418 std::shared_ptr<ExtensionPoint>
point(processExtensionPoint(curChild, bundle));
419 bundle->addExtensionPoint(point);
424 if(xmlStrcmp(curChild->name, (
const xmlChar*) LIBRARY.c_str()) == 0)
426 std::shared_ptr<dl::Library> library(processLibrary(curChild));
427 bundle->addLibrary(library);
432 if(xmlStrcmp(curChild->name, (
const xmlChar*) REQUIREMENT.c_str()) == 0)
434 const std::string requirement(processRequirement(curChild));
435 bundle->addRequirement(requirement);
439 if(xmlStrcmp(curChild->name, (
const xmlChar*) POINT.c_str()) == 0)
441 SLM_FATAL(
"This xml element ( <point ... > </point> ) is deprecated (" + location.string() +
")" );
451 const std::string BundleDescriptorReader::processRequirement(xmlNodePtr node)
455 std::string identifier;
456 for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
458 if(xmlStrcmp(curAttr->name, (
const xmlChar*) ID.c_str()) == 0)
460 identifier = (
const char*) curAttr->children->content;
466 if(identifier.length() == 0)
static FWRUNTIME_API Runtime * getDefault()
Retrieves the default runtime instance.
static FWRUNTIME_API const BundleContainer createBundles(const boost::filesystem::path &location)
Creates all bundles that are found at the given location.
Defines the extension class.
Defines the runtime exception class.
FWRUNTIME_API const std::string getErrorLog() const
Retrieves the error log content.
FWRUNTIME_API bool validate(const boost::filesystem::path &xmlFile)
Validates the given file.
static FWRUNTIME_API std::shared_ptr< ConfigurationElement > processConfigurationElement(xmlNodePtr node, const std::shared_ptr< Bundle > bundle)
Processes a configuration element XML node.
Defines the extension point class.
#define OSLM_INFO(message)
Defines the configuration element class.
FWRUNTIME_API std::shared_ptr< Bundle > findBundle(const std::string &identifier, const Version &version=Version()) const
Retrieves the bundle for the specified idenfier.
static FWRUNTIME_API std::shared_ptr< Bundle > createBundle(const boost::filesystem::path &location)
Look for a descriptor at the specified location, reads it and creates a bundle with it...
The namespace fwRuntime contains classes to manage bundle, configuration element, extension point in ...
#define SLM_FATAL(message)
Implements an XML validator.
Defines the module class.This class is only a bridge to a native module implementor.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
std::pair< std::shared_ptr< ExtensionPoint >, std::vector< std::shared_ptr< Extension > > > PointExtensionsPairType
Pair of created extension point associated with extensions.
Defines the bundle class.
Holds version information for libraries and bundles.
#define OSLM_WARN_IF(message, cond)
FWRUNTIME_API::boost::filesystem::path getWorkingPath() const
Get the path where Bundles and share folder are located.