]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Possibility to load proprietary plugins on startup and check the license validity
authorArtem Zhidkov <Artem.Zhidkov@gmail.com>
Tue, 13 Apr 2021 06:33:11 +0000 (09:33 +0300)
committerazv <azv@opencascade.com>
Tue, 28 Dec 2021 19:25:01 +0000 (22:25 +0300)
src/Config/Config_Keywords.h
src/Config/Config_ModuleReader.cpp
src/Config/Config_ModuleReader.h
src/Model/Model_Session.cpp
src/Model/Model_Session.h
src/ModelAPI/ModelAPI_Events.cpp
src/ModelAPI/ModelAPI_Events.h
src/ModelAPI/ModelAPI_Session.h
src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_IModule.h
src/PartSet/PartSet_Module.cpp

index cfbbcc2a1149851f320fd9bbaf8db2c384717eb4..4149e38167aec4516cf9f620875710146773b28c 100644 (file)
@@ -146,6 +146,7 @@ MAYBE_UNUSED const static char* PLUGIN_SCRIPT = "script";
 MAYBE_UNUSED const static char* PLUGIN_DEPENDENCY = "dependency";
 MAYBE_UNUSED const static char* PLUGIN_USES = "uses";
 MAYBE_UNUSED const static char* PLUGIN_DOCSECTION = "docsection";
+MAYBE_UNUSED const static char* PLUGIN_LICENSE = "license";
 
 /*
  * Hardcoded xml entities of dataModel.xml
index afbd79c85ac657a19d2cc9b90a9a866658f304f6..83ea39d23d87815e6b72ede593cb36ee91feb438 100644 (file)
@@ -62,6 +62,16 @@ const std::map<std::string, std::string>& Config_ModuleReader::featuresInFiles()
   return myFeaturesInFiles;
 }
 
+const std::map<std::string, std::string>& Config_ModuleReader::proprietaryFeatures() const
+{
+  return myProprietaryFeatures;
+}
+
+const std::set<std::string>& Config_ModuleReader::proprietaryPlugins() const
+{
+  return myProprietaryPlugins;
+}
+
 const std::set<std::string>& Config_ModuleReader::modulePluginFiles() const
 {
   return myPluginFiles;
@@ -81,6 +91,10 @@ std::string Config_ModuleReader::getModuleName()
 void Config_ModuleReader::addFeature(const std::string& theFeatureName,
                                      const std::string& thePluginConfig)
 {
+  if (myProprietaryFeatures.count(theFeatureName)) {
+    myProprietaryFeatures.erase(theFeatureName);
+  }
+
   if (myFeaturesInFiles.count(theFeatureName)) {
     std::string anErrorMsg = "Can not register feature '%1' in plugin '%2'."
       " There is a feature with the same ID.";
@@ -92,6 +106,21 @@ void Config_ModuleReader::addFeature(const std::string& theFeatureName,
   myFeaturesInFiles[theFeatureName] = thePluginConfig;
 }
 
+void Config_ModuleReader::addFeatureRequireLicense(const std::string& theFeatureName,
+                                                   const std::string& thePluginConfig)
+{
+  if (myFeaturesInFiles.count(theFeatureName) ||
+      myProprietaryFeatures.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;
+  }
+
+  myProprietaryFeatures[theFeatureName] = thePluginConfig;
+}
+
 void Config_ModuleReader::processNode(xmlNodePtr theNode)
 {
   if (isNode(theNode, NODE_PLUGIN, NULL)) {
@@ -112,10 +141,19 @@ void Config_ModuleReader::processNode(xmlNodePtr theNode)
       Events_Loop::loop()->send(aMess);
     }
 
+    std::string aLicense = getProperty(theNode, PLUGIN_LICENSE);
+    std::transform(aLicense.begin(), aLicense.end(), aLicense.begin(), ::tolower);
+    bool isLicensed = aLicense == "true";
+    if (isLicensed)
+      myProprietaryPlugins.insert(aPluginName);
+
     std::list<std::string> aFeatures = importPlugin(aPluginName, aPluginConf, aPluginDocSection);
     std::list<std::string>::iterator it = aFeatures.begin();
     for (; it != aFeatures.end(); it++) {
-      addFeature(*it, aPluginConf);
+      if (isLicensed)
+        addFeatureRequireLicense(*it, aPluginConf);
+      else
+        addFeature(*it, aPluginConf);
     }
   }
 }
index ce6198edb6e991bc1acba5a4d32d8486863f31fb..24ae9a3b12e6fdb3f8da44ac7db560b28683b960 100644 (file)
@@ -49,6 +49,12 @@ class Config_ModuleReader : public Config_XMLReader
   /// Returns map that describes which file contains a feature
   /// (the feature is key, the file is value)
   CONFIG_EXPORT const std::map<std::string, std::string>& featuresInFiles() const;
+  /// Returns map containing features, which have licensed.
+  /// The valid license should be confirmed first
+  /// (the feature is key, the file is value)
+  CONFIG_EXPORT const std::map<std::string, std::string>& proprietaryFeatures() const;
+  /// Returns proprietary plugins
+  CONFIG_EXPORT const std::set<std::string>& proprietaryPlugins() const;
   /// Returns list of module's xml files
   CONFIG_EXPORT const std::set<std::string>& modulePluginFiles() const;
   /// Returns module name: an xml attribute from the root of the plugins.xml:
@@ -86,14 +92,22 @@ class Config_ModuleReader : public Config_XMLReader
   /// Save feature in myFeaturesInFiles.
   /// Generates an error if the feature name is already registered.
   void addFeature(const std::string& theFeatureName, const std::string& thePluginConfig);
+  /// Save feature in myFeaturesRequireLicense.
+  /// Generates an error if the feature name is already registered.
+  void addFeatureRequireLicense(const std::string& theFeatureName,
+                                const std::string& thePluginConfig);
 
  private:
   std::map<std::string, std::string> myFeaturesInFiles; ///< a feature name is key, a file is value
+  /// list of features, which need a license, and their config files
+  std::map<std::string, std::string> myProprietaryFeatures;
   std::set<std::string> myPluginFiles; ///< a feature name is key, a file is value
   /// a plugin name is key, a plugin type is value
   static std::map<std::string, PluginType> myPluginTypes;
   static std::set<std::string> myDependencyModules; ///< set of loaded modules
   const char* myEventGenerated; ///< gives ability to send Feature_Messages to various listeners
+
+  std::set<std::string> myProprietaryPlugins; ///< list of plugins protected by license
 };
 
 #endif /* CONFIG_XMLMODULEREADER_H_ */
index eb4ab5ff98229ea4a7fc46074a9352c61c304bc8..38ed84cfcc6d40a097513abb121253bbfa88eb5d 100644 (file)
@@ -179,6 +179,11 @@ std::list<std::string> Model_Session::redoList()
   return ROOT_DOC->redoList();
 }
 
+bool Model_Session::checkLicense(const std::string& thePluginName)
+{
+  return getPlugin(thePluginName);
+}
+
 ModelAPI_Plugin* Model_Session::getPlugin(const std::string& thePluginName)
 {
   if (myPluginObjs.find(thePluginName) == myPluginObjs.end()) {
index 218659d5a887dc4c5734fa32ad4eaf9435df82e3..88397ec4ce886b058126db18cd2aa9551345a7a0 100644 (file)
@@ -127,6 +127,9 @@ class Model_Session : public ModelAPI_Session, public Events_Listener
   /// the plugin manager on call of the feature)
   MODEL_EXPORT virtual void registerPlugin(ModelAPI_Plugin* thePlugin);
 
+  /// Verifies the license for the plugin is valid
+  MODEL_EXPORT virtual bool checkLicense(const std::string& thePluginName);
+
   /// Processes the configuration file reading
   MODEL_EXPORT virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
 
index 506b261893205208fa443108f8f31811df5be0df..a340738947572f535e9d55289a1a4535796a38d6 100644 (file)
@@ -469,3 +469,23 @@ const ListOfShape& ModelAPI_ShapesFailedMessage::shapes() const
 {
   return myShapes;
 }
+
+
+// =====   ModelAPI_FeaturesLicenseValidMessage   =====
+ModelAPI_FeaturesLicenseValidMessage::ModelAPI_FeaturesLicenseValidMessage(
+    const Events_ID theID, const void* theSender)
+  : Events_Message(theID, theSender)
+{}
+
+ModelAPI_FeaturesLicenseValidMessage::~ModelAPI_FeaturesLicenseValidMessage()
+{}
+
+void ModelAPI_FeaturesLicenseValidMessage::setFeatures(const std::set<std::string>& theFeatures)
+{
+  myFeatures = theFeatures;
+}
+
+const std::set<std::string>& ModelAPI_FeaturesLicenseValidMessage::features() const
+{
+  return myFeatures;
+}
index 2ebd25b0f37d1f7f6f9ab529d1152ea87d86692b..b32ef747ff9b53c812fb4fde4392db28b9ca209e 100644 (file)
@@ -119,10 +119,12 @@ MAYBE_UNUSED static const char * EVENT_DOF_OBJECTS = "DoFObjects";
 /// Event ID that requests updates visual attributes for presentations
 MAYBE_UNUSED static const char * EVENT_VISUAL_ATTRIBUTES = "UpdateVisualAttributes";
 
-
 /// Event ID that 1D-fillet failed (comes with ModelAPI_ShapesFailedMessage)
 MAYBE_UNUSED static const char * EVENT_OPERATION_SHAPES_FAILED = "OperationShapesFailed";
 
+/// Event ID that license of specified features is checked and valid
+MAYBE_UNUSED static const char * EVENT_FEATURE_LICENSE_VALID = "FeaturesLicenseValid";
+
 /// Message that feature was changed (used for Object Browser update): moved, updated and deleted
 class MODELAPI_EXPORT ModelAPI_ObjectUpdatedMessage : public Events_MessageGroup
 {
@@ -656,4 +658,28 @@ private:
   std::list< std::shared_ptr<GeomAPI_Shape> > myShapes;
 };
 
+/// Message that sends the features which license is checked and valid
+class ModelAPI_FeaturesLicenseValidMessage : public Events_Message
+{
+public:
+  /// Creates an message
+  MODELAPI_EXPORT
+  ModelAPI_FeaturesLicenseValidMessage(const Events_ID theID, const void* theSender = 0);
+  /// Default destructor
+  MODELAPI_EXPORT virtual ~ModelAPI_FeaturesLicenseValidMessage();
+  /// Static. Returns EventID of the message.
+  MODELAPI_EXPORT static Events_ID eventId()
+  {
+    return Events_Loop::eventByName(EVENT_FEATURE_LICENSE_VALID);
+  }
+
+  /// Sets list of features with valid license
+  MODELAPI_EXPORT void setFeatures(const std::set<std::string>& theFeatures);
+  /// Returns list of features with valid license
+  MODELAPI_EXPORT const std::set<std::string>& features() const;
+
+private:
+  std::set<std::string> myFeatures;
+};
+
 #endif
index 339263fb0f0ceccd48008f63fdf2829226396c6f..7a1b2f40deb85da888ff3a020e4cf07e1447311b 100644 (file)
@@ -97,6 +97,9 @@ class MODELAPI_EXPORT ModelAPI_Session
   /// the plugin manager on call of the feature)
   virtual void registerPlugin(ModelAPI_Plugin* thePlugin) = 0;
 
+  /// Verifies the license for the plugin is valid
+  virtual bool checkLicense(const std::string& thePluginName) = 0;
+
   /// Returns the root document of the application (that may contains sub-documents)
   virtual std::shared_ptr<ModelAPI_Document> moduleDocument() = 0;
 
index 678837a4db2023c5911493d20e5f44e6d41310f4..90124f8d9b4a38dd0629ce62a62a8c2fb3ffdf02 100644 (file)
@@ -34,6 +34,7 @@
 #include "ModuleBase_Dialog.h"
 #include "ModuleBase_IErrorMgr.h"
 
+#include <Events_InfoMessage.h>
 #include <Events_Loop.h>
 #include <Events_Message.h>
 
@@ -219,6 +220,33 @@ void ModuleBase_IModule::createFeatures()
   Config_ModuleReader aXMLReader = Config_ModuleReader();
   aXMLReader.readAll();
   myFeaturesInFiles = aXMLReader.featuresInFiles();
+  myProprietaryFeatures = aXMLReader.proprietaryFeatures();
+  myProprietaryPlugins = aXMLReader.proprietaryPlugins();
+}
+
+void ModuleBase_IModule::processProprietaryFeatures()
+{
+  std::set<std::string>::iterator it = myFeaturesValidLicense.begin();
+  while (it != myFeaturesValidLicense.end()) {
+    std::map<std::string, std::string>::iterator aFound = myProprietaryFeatures.find(*it);
+    if (aFound == myProprietaryFeatures.end())
+      ++it;
+    else {
+      myFeaturesInFiles[aFound->first] = aFound->second;
+      myProprietaryFeatures.erase(aFound);
+      std::set<std::string>::iterator aRemoveIt = it++;
+      myFeaturesValidLicense.erase(aRemoveIt);
+    }
+  }
+}
+
+void ModuleBase_IModule::loadProprietaryPlugins()
+{
+  for (std::set<std::string>::const_iterator itP = myProprietaryPlugins.begin();
+       itP != myProprietaryPlugins.end(); ++itP) {
+    if (!ModelAPI_Session::get()->checkLicense(*itP))
+      Events_InfoMessage(*itP, "License of %1 plugin is not valid or not exist!").arg(*itP).send();
+  }
 }
 
 
index 3c3544e11603ec16b3d3d8f64739d56944204cc8..6ab1badf267b0f3c36d37ed58177135229d01982 100644 (file)
@@ -443,12 +443,24 @@ protected:
   /// Returns new instance of operation object (used in createOperation for customization)
   virtual ModuleBase_Operation* getNewOperation(const std::string& theFeatureId);
 
+  /// Load plugins required license
+  void loadProprietaryPlugins();
+
+  /// Collect features, which have valid license
+  void processProprietaryFeatures();
+
 protected:
   /// Reference to workshop
   ModuleBase_IWorkshop* myWorkshop;
 
   /// Map of features in XML
   std::map<std::string, std::string> myFeaturesInFiles;
+  /// Map of features in XML, which require license but not confirmed yet
+  std::map<std::string, std::string> myProprietaryFeatures;
+  /// Proprietary plugins
+  std::set<std::string> myProprietaryPlugins;
+  /// Features, which have valid license
+  std::set<std::string> myFeaturesValidLicense;
 
   std::map<ModuleBase_SelectionFilterType, Handle(SelectMgr_Filter)> mySelectionFilters;
 
index 7c66e17481654bd3fa1e60d3660ed607095f36ff..8a703fa0fd813e926275e89c47715180c84035d0 100644 (file)
@@ -188,6 +188,7 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
   Events_Loop* aLoop = Events_Loop::loop();
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED));
   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_LICENSE_VALID));
 
   registerSelectionFilter(SF_GlobalFilter, new PartSet_GlobalFilter(myWorkshop));
   registerSelectionFilter(SF_FilterInfinite, new PartSet_FilterInfinite(myWorkshop));
@@ -287,6 +288,7 @@ void PartSet_Module::createFeatures()
   ModuleBase_IModule::createFeatures();
   myRoot = new PartSet_RootNode();
   myRoot->setWorkshop(workshop());
+  ModuleBase_IModule::loadProprietaryPlugins();
 }
 
 
@@ -1711,6 +1713,12 @@ void PartSet_Module::processEvent(const std::shared_ptr<Events_Message>& theMess
         mySketchMgr->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop);
     }
   }
+  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_LICENSE_VALID)) {
+    std::shared_ptr<ModelAPI_FeaturesLicenseValidMessage> aMsg =
+      std::dynamic_pointer_cast<ModelAPI_FeaturesLicenseValidMessage>(theMessage);
+    myFeaturesValidLicense.insert(aMsg->features().begin(), aMsg->features().end());
+    processProprietaryFeatures();
+  }
 }
 
 //******************************************************