X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FConfig%2FConfig_ModuleReader.cpp;h=526b9965f51aebc1b97b482991fa5d2a1fa2da66;hb=c6a92152ecb67e86489d0a17c8df5fa2e5bcf84e;hp=1a6d1c7ce989770fc0433bb75f44c041b1faa1df;hpb=e607e2c793a83dc30d483e1819f44c3497a08555;p=modules%2Fshaper.git diff --git a/src/Config/Config_ModuleReader.cpp b/src/Config/Config_ModuleReader.cpp index 1a6d1c7ce..526b9965f 100644 --- a/src/Config/Config_ModuleReader.cpp +++ b/src/Config/Config_ModuleReader.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + /* * Config_ModuleReader.cpp * @@ -5,35 +7,51 @@ * Author: sbh */ +#include +#include #include #include +#include + +#include +#include -#include -#include +// Have to be included before std headers +#include -#ifdef _DEBUG +//Necessary for cerr #include +#include + +#ifdef WIN32 +#include +#pragma warning(disable : 4996) // for getenv +#else +#include #endif -//Hardcoded xml entities -// * Nodes -const static char* NODE_PLUGIN = "plugin"; -const static char* NODE_PLUGINS = "plugins"; +std::map Config_ModuleReader::myPluginTypes; -// * Properties -const static char* PLUGINS_MODULE = "module"; -const static char* PLUGIN_CONFIG = "configuration"; -const static char* PLUGIN_LIBRARY = "library"; +Config_ModuleReader::Config_ModuleReader(const char* theEventGenerated) + : Config_XMLReader(PLUGIN_FILE), + myEventGenerated(theEventGenerated) +{ + myHaveSalome = false; + char* anEnv = getenv("SALOME_ROOT_DIR"); + std::string value = normalize(anEnv); + if (!value.empty()) { + myHaveSalome = true; + } +} -Config_ModuleReader::Config_ModuleReader() - : Config_XMLReader("plugins.xml"), - m_isAutoImport(false) +Config_ModuleReader::~Config_ModuleReader() { } -Config_ModuleReader::~Config_ModuleReader() +const std::map& Config_ModuleReader::featuresInFiles() const { + return myFeaturesInFiles; } /* @@ -51,11 +69,20 @@ std::string Config_ModuleReader::getModuleName() */ void Config_ModuleReader::processNode(xmlNodePtr theNode) { - if(isNode(theNode, NODE_PLUGIN, NULL)) { - std::string aPluginName = getProperty(theNode, PLUGIN_CONFIG); - if(m_isAutoImport) - importPlugin(aPluginName); - m_pluginsList.push_back(aPluginName); + if (isNode(theNode, NODE_PLUGIN, NULL)) { + bool isAvailable = isAvaliableOnThisPlatform(getProperty(theNode, PLUGIN_PLATFORM)); + if (!isAvailable) + return; + std::string aPluginConf = getProperty(theNode, PLUGIN_CONFIG); + std::string aPluginLibrary = getProperty(theNode, PLUGIN_LIBRARY); + std::string aPluginScript = getProperty(theNode, PLUGIN_SCRIPT); + std::string aPluginName = addPlugin(aPluginLibrary, aPluginScript, aPluginConf); + + std::list aFeatures = importPlugin(aPluginName, aPluginConf); + std::list::iterator it = aFeatures.begin(); + for (; it != aFeatures.end(); it++) { + myFeaturesInFiles[*it] = aPluginConf; + } } } @@ -64,18 +91,131 @@ bool Config_ModuleReader::processChildren(xmlNodePtr theNode) return isNode(theNode, NODE_PLUGINS, NULL); } -void Config_ModuleReader::importPlugin(const std::string& thePluginName) +std::list Config_ModuleReader::importPlugin(const std::string& thePluginLibrary, + const std::string& thePluginXmlConf) { - Config_FeatureReader aReader(thePluginName); + if (thePluginXmlConf.empty()) { //probably a third party library + loadLibrary(thePluginLibrary); + return std::list(); + } + + Config_FeatureReader aReader = Config_FeatureReader(thePluginXmlConf, + thePluginLibrary, + myEventGenerated); aReader.readAll(); + return aReader.features(); } -void Config_ModuleReader::setAutoImport(bool enabled) +std::string Config_ModuleReader::addPlugin(const std::string& aPluginLibrary, + const std::string& aPluginScript, + const std::string& aPluginConf) { - m_isAutoImport = enabled; + PluginType aType = Config_ModuleReader::Binary; + std::string aPluginName; + if (!aPluginLibrary.empty()) { + aPluginName = aPluginLibrary; + if (aPluginConf.empty()) { + aType = Config_ModuleReader::Intrenal; + } + } else if (!aPluginScript.empty()) { + aPluginName = aPluginScript; + aType = Config_ModuleReader::Python; + } + if(!aPluginName.empty()) { + myPluginTypes[aPluginName] = aType; + } + + return aPluginName; } -const std::list& Config_ModuleReader::pluginsList() const +void Config_ModuleReader::loadPlugin(const std::string thePluginName) { - return m_pluginsList; + PluginType aType = Config_ModuleReader::Binary; + if(myPluginTypes.find(thePluginName) != myPluginTypes.end()) { + aType = myPluginTypes.at(thePluginName); + } + switch (aType) { + case Config_ModuleReader::Python: + loadScript(thePluginName); + break; + case Config_ModuleReader::Binary: + case Config_ModuleReader::Intrenal: + default: + loadLibrary(thePluginName); + break; + } } + +bool Config_ModuleReader::isAvaliableOnThisPlatform(const std::string& thePluginPlatform) +{ + bool result = true; + PluginPlatform aPlatform = All; + std::string aPlatformName = normalize(thePluginPlatform) ; + if (aPlatformName == PLUGIN_PLATFORM_SALOME) { + aPlatform = Salome; + } else if (aPlatformName == PLUGIN_PLATFORM_NEWGEOM) { + aPlatform = OpenParts; + } else if (!thePluginPlatform.empty()) { + Events_Error::send("Unknown platform: " + thePluginPlatform); + } + if (aPlatform == All) { + result = true; + } else if (myHaveSalome) { + result = aPlatform == Salome; + } else { + result = aPlatform == OpenParts; + } + return result; + +} + +void Config_ModuleReader::loadScript(const std::string theFileName) +{ + /* aquire python thread */ + PyGILState_STATE gstate = PyGILState_Ensure(); + + PyObject* module = PyImport_ImportModule(theFileName.c_str()); + if (!module) { + std::string anErrorMsg = "An error occured while importing " + theFileName; + //Get detailed error message: + if (PyErr_Occurred()) { + PyObject *pstr, *ptype, *pvalue, *ptraceback; + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); + pstr = PyObject_Str(pvalue); + std::string aPyError = std::string(PyString_AsString(pstr)); + if (!aPyError.empty()) { + anErrorMsg += ":\n" + aPyError; + } + Py_XDECREF(pstr); + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + } + Events_Error::send(anErrorMsg); + } + + /* release python thread */ + PyGILState_Release(gstate); +} + +void Config_ModuleReader::loadLibrary(const std::string theLibName) +{ + std::string aFileName = library(theLibName); + if (aFileName.empty()) + return; + +#ifdef WIN32 + HINSTANCE aModLib = ::LoadLibrary(aFileName.c_str()); +#else + void* aModLib = dlopen( aFileName.c_str(), RTLD_LAZY | RTLD_GLOBAL ); +#endif + if(!aModLib && theLibName != "DFBrowser") { // don't show error for internal debugging tool + std::string anErrorMsg = "Failed to load " + aFileName; + #ifndef WIN32 + anErrorMsg += ": " + std::string(dlerror()); + #endif + Events_Error::send(anErrorMsg); + } +} +