X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FConfig%2FConfig_ModuleReader.cpp;h=2720bc308c9f010c2e5466281828a336991fb618;hb=f51f8ab55887ac6eff49fb9937a460abe1956517;hp=d0da80ba0a8f0914a27ea7baa8706096f209f066;hpb=ea9b3a766e6401626c170e3ae5f591f67af22271;p=modules%2Fshaper.git diff --git a/src/Config/Config_ModuleReader.cpp b/src/Config/Config_ModuleReader.cpp index d0da80ba0..2720bc308 100644 --- a/src/Config/Config_ModuleReader.cpp +++ b/src/Config/Config_ModuleReader.cpp @@ -1,17 +1,30 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D +// Copyright (C) 2014-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// -/* - * Config_ModuleReader.cpp - * - * Created on: Mar 20, 2014 - * Author: sbh - */ +#include #include #include #include #include -#include +#include +#include #include #include @@ -31,18 +44,12 @@ #endif std::map Config_ModuleReader::myPluginTypes; +std::set Config_ModuleReader::myDependencyModules; 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() @@ -54,7 +61,12 @@ const std::map& Config_ModuleReader::featuresInFiles() return myFeaturesInFiles; } -/* +const std::set& Config_ModuleReader::modulePluginFiles() const +{ + return myPluginFiles; +} + +/*! * Get module name from plugins.xml * (property "module") */ @@ -64,24 +76,44 @@ std::string Config_ModuleReader::getModuleName() return getProperty(aRoot, PLUGINS_MODULE); } -/* - * - */ + +void Config_ModuleReader::addFeature(const std::string& theFeatureName, + const std::string& thePluginConfig) +{ + if (myFeaturesInFiles.count(theFeatureName)) { + std::string anErrorMsg = "Can not register feature '%1' in plugin '%2'." + " There is a feature with the same ID."; + Events_InfoMessage("Config_ModuleReader", anErrorMsg) + .arg(theFeatureName).arg(thePluginConfig).send(); + return; + } + + myFeaturesInFiles[theFeatureName] = thePluginConfig; +} + void Config_ModuleReader::processNode(xmlNodePtr theNode) { if (isNode(theNode, NODE_PLUGIN, NULL)) { - bool isAvailable = isAvaliableOnThisPlatform(getProperty(theNode, PLUGIN_PLATFORM)); - if (!isAvailable) + if (!hasRequiredModules(theNode)) return; std::string aPluginConf = getProperty(theNode, PLUGIN_CONFIG); + if (!aPluginConf.empty()) + myPluginFiles.insert(aPluginConf); std::string aPluginLibrary = getProperty(theNode, PLUGIN_LIBRARY); std::string aPluginScript = getProperty(theNode, PLUGIN_SCRIPT); std::string aPluginName = addPlugin(aPluginLibrary, aPluginScript, aPluginConf); + std::string aUsesPlugin = getProperty(theNode, PLUGIN_USES); + if (!aUsesPlugin.empty()) { // send information about the plugin dependencies + std::shared_ptr aMess(new Config_PluginMessage( + Events_Loop::loop()->eventByName(Config_PluginMessage::EVENT_ID()), aPluginName)); + aMess->setUses(aUsesPlugin); + Events_Loop::loop()->send(aMess); + } std::list aFeatures = importPlugin(aPluginName, aPluginConf); std::list::iterator it = aFeatures.begin(); for (; it != aFeatures.end(); it++) { - myFeaturesInFiles[*it] = aPluginConf; + addFeature(*it, aPluginConf); } } } @@ -91,6 +123,18 @@ bool Config_ModuleReader::processChildren(xmlNodePtr theNode) return isNode(theNode, NODE_PLUGINS, NULL); } +bool Config_ModuleReader::hasRequiredModules(xmlNodePtr theNode) const +{ + std::string aRequiredModule = normalize(getProperty(theNode, PLUGIN_DEPENDENCY)); + if(aRequiredModule.empty()) + return true; + std::set::iterator it = myDependencyModules.begin(); + for ( ; it != myDependencyModules.end(); it++ ) { + if (*it == aRequiredModule) return true; + } + return false; +} + std::list Config_ModuleReader::importPlugin(const std::string& thePluginLibrary, const std::string& thePluginXmlConf) { @@ -124,12 +168,18 @@ std::string Config_ModuleReader::addPlugin(const std::string& aPluginLibrary, if(!aPluginName.empty()) { myPluginTypes[aPluginName] = aType; } - + addDependencyModule(aPluginName); return aPluginName; } -void Config_ModuleReader::loadPlugin(const std::string thePluginName) +void Config_ModuleReader::loadPlugin(const std::string& thePluginName) { + // informs model that plugin loading is started + static const Events_ID kEVENT_ID = + Events_Loop::loop()->eventByName(Config_PluginMessage::EVENT_ID()); + std::shared_ptr aMess(new Config_PluginMessage(kEVENT_ID, thePluginName)); + Events_Loop::loop()->send(aMess); + PluginType aType = Config_ModuleReader::Binary; if(myPluginTypes.find(thePluginName) != myPluginTypes.end()) { aType = myPluginTypes.at(thePluginName); @@ -146,73 +196,73 @@ void Config_ModuleReader::loadPlugin(const std::string thePluginName) } } -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) +void Config_ModuleReader::loadScript(const std::string& theFileName, bool theSendErr) { - /* aquire python thread */ + /* acquire python thread */ PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject* module = PyImport_ImportModule(theFileName.c_str()); + PyObject* module = PyImport_ImportModule(theFileName.c_str()); if (!module) { - std::string anErrorMsg = "An error occured while importing " + theFileName; + std::string anErrorMsg = "An error occurred while importing " + theFileName; //Get detailed error message: if (PyErr_Occurred()) { - PyObject *ptype, *pvalue, *ptraceback; + PyObject *pstr, *ptype, *pvalue, *ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback); - std::string aPyError = std::string(PyString_AsString(pvalue)); + PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); + pstr = PyObject_Str(pvalue); + std::string aPyError = std::string(PyUnicode_AsUTF8(pstr)); if (!aPyError.empty()) { anErrorMsg += ":\n" + aPyError; } + Py_XDECREF(pstr); Py_XDECREF(ptype); Py_XDECREF(pvalue); Py_XDECREF(ptraceback); } - Events_Error::send(anErrorMsg); + if (theSendErr) + Events_InfoMessage("Config_ModuleReader", anErrorMsg).send(); } /* release python thread */ PyGILState_Release(gstate); } -void Config_ModuleReader::loadLibrary(const std::string theLibName) +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 + #ifdef WIN32 + HINSTANCE aModLib = ::LoadLibraryA(aFileName.c_str()); + #else void* aModLib = dlopen( aFileName.c_str(), RTLD_LAZY | RTLD_GLOBAL ); -#endif + #endif if(!aModLib && theLibName != "DFBrowser") { // don't show error for internal debugging tool +// LCOV_EXCL_START std::string anErrorMsg = "Failed to load " + aFileName; - #ifndef WIN32 + #ifdef WIN32 + DWORD dwLastError = ::GetLastError(); + LPSTR messageBuffer = NULL; + size_t size = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwLastError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&messageBuffer, 0, NULL); + anErrorMsg += ": " + std::string(messageBuffer, size); + #else anErrorMsg += ": " + std::string(dlerror()); #endif - Events_Error::send(anErrorMsg); + std::cerr << anErrorMsg << std::endl; + Events_InfoMessage("Config_ModuleReader", anErrorMsg).send(); +// LCOV_EXCL_STOP } } +void Config_ModuleReader::addDependencyModule(const std::string& theModuleName) +{ + myDependencyModules.insert(normalize(theModuleName)); +} +