Salome HOME
Make edition transaction where actually nothing was changed as empty one and do not...
[modules/shaper.git] / src / Model / Model_Validator.cpp
index 83a4e04cb43bb9c898830d417ec18633412dbdb2..6795e43e1b2b13cb7387d4ff8e3515534a25ac4b 100644 (file)
@@ -4,13 +4,17 @@
 // Created:     2 Jul 2014
 // Author:      Mikhail PONIKAROV
 
-#include <Model_Validator.h>
-#include <Model_FeatureValidator.h>
-#include <ModelAPI_Feature.h>
+#include "Model_Validator.h"
+
+#include "Model_AttributeValidator.h"
+#include "Model_FeatureValidator.h"
+
 #include <ModelAPI_Attribute.h>
-#include <ModelAPI_Data.h>
-#include <ModelAPI_AttributeValidator.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeValidator.h>
+#include <ModelAPI_Feature.h>
+#include <Model_Data.h>
+
 #include <Events_Error.h>
 
 void Model_ValidatorsFactory::registerValidator(const std::string& theID,
@@ -109,13 +113,14 @@ void Model_ValidatorsFactory::validators(const std::string& theFeatureID, const
       }
     }
   }
+  addDefaultAttributeValidators(theValidators);
 }
 
 Model_ValidatorsFactory::Model_ValidatorsFactory()
   : ModelAPI_ValidatorsFactory()
 {
-  const static std::string kDefaultId = "Model_FeatureValidator";
-  registerValidator(kDefaultId, new Model_FeatureValidator);
+  registerValidator("Model_FeatureValidator", new Model_FeatureValidator);
+  registerValidator("Model_AttributeValidator", new Model_AttributeValidator);
 }
 
 const ModelAPI_Validator* Model_ValidatorsFactory::validator(const std::string& theID) const
@@ -135,13 +140,23 @@ void Model_ValidatorsFactory::addDefaultValidators(Validators& theValidators) co
   theValidators.push_back(std::make_pair(kDefaultId, std::list<std::string>()));
 }
 
-bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>& theFeature) const
+void Model_ValidatorsFactory::addDefaultAttributeValidators(Validators& theValidators) const
 {
-  const static std::string kDefaultId = "Model_FeatureValidator";
+  const static std::string kDefaultId = "Model_AttributeValidator";
+  if (!validator(kDefaultId))
+    return;
+  theValidators.push_back(std::make_pair(kDefaultId, std::list<std::string>()));
+}
 
-  ModelAPI_ExecState anExecState = theFeature->data()->execState();
-  theFeature->setError("", false);
-  theFeature->data()->execState(anExecState);
+bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>& theFeature) const
+{
+  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theFeature->data());
+  if (aData.get() && aData->isValid()) {
+    if (aData->execState() == ModelAPI_StateDone)
+      aData->eraseErrorString(); // no error => erase the information string
+  } else {
+    return false; // feature is broken, already not presented in the data structure
+  }
 
   // check feature validators first
   Validators aValidators;
@@ -164,7 +179,7 @@ bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>&
         if (!aFValidator->isValid(theFeature, anArguments, anError)) {
           if (anError.empty())
             anError = "Unknown error.";
-          anError = "Feature invalidated by \"" + aValidatorID + "\" with error: " + anError;
+          anError = aValidatorID + ": " + anError;
           theFeature->setError(anError, false);
           theFeature->data()->execState(ModelAPI_StateInvalidArgument);
           return false;
@@ -191,9 +206,8 @@ bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>&
   //    }
   //  }
   //}
-  
+
   // check all attributes for validity
-  std::shared_ptr<ModelAPI_Data> aData = theFeature->data();
   // Validity of data is checked by "Model_FeatureValidator" (kDefaultId)
   // if (!aData || !aData->isValid())
   //   return false;
@@ -209,7 +223,7 @@ bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>&
     if (!validate(anAttribute, aValidatorID, anError)) {
       if (anError.empty())
         anError = "Unknown error.";
-      anError = "Attribute \"" + anAttributeID + "\" invalidated by \"" + aValidatorID + "\" with error: " + anError;
+      anError = anAttributeID + " - " + aValidatorID + ": " + anError;
       theFeature->setError(anError, false);
       theFeature->data()->execState(ModelAPI_StateInvalidArgument);
       return false;
@@ -300,28 +314,36 @@ bool Model_ValidatorsFactory::isConcealed(std::string theFeature, std::string th
 void Model_ValidatorsFactory::registerCase(std::string theFeature, std::string theAttribute,
     std::string theSwitchId, std::string theCaseId)
 {
-  std::map<std::string, std::map<std::string, std::pair<std::string, std::string> > >::iterator 
-    aFindFeature = myCases.find(theFeature);
+  std::map<std::string, std::map<std::string, std::pair<std::string, std::set<std::string> > > >
+    ::iterator aFindFeature = myCases.find(theFeature);
   if (aFindFeature == myCases.end()) {
-    myCases[theFeature] = std::map<std::string, std::pair<std::string, std::string> >();
+    myCases[theFeature] = std::map<std::string, std::pair<std::string, std::set<std::string> > >();
     aFindFeature = myCases.find(theFeature);
   }
-  (aFindFeature->second)[theAttribute] = std::pair<std::string, std::string>(theSwitchId, theCaseId);
+  std::map<std::string, std::pair<std::string, std::set<std::string> > >::iterator aFindAttrID =
+    aFindFeature->second.find(theAttribute);
+  if (aFindAttrID == aFindFeature->second.end()) {
+    aFindFeature->second[theAttribute] =
+      std::pair<std::string, std::set<std::string> >(theSwitchId, std::set<std::string>());
+    aFindAttrID = aFindFeature->second.find(theAttribute);
+  }
+  aFindAttrID->second.second.insert(theCaseId);
 }
 
-bool Model_ValidatorsFactory::isCase(
-  FeaturePtr theFeature, std::string theAttribute)
+bool Model_ValidatorsFactory::isCase(FeaturePtr theFeature, std::string theAttribute)
 {
-  std::map<std::string, std::map<std::string, std::pair<std::string, std::string> > >::iterator 
-    aFindFeature = myCases.find(theFeature->getKind());
+  std::map<std::string, std::map<std::string, std::pair<std::string, std::set<std::string> > > >
+    ::iterator aFindFeature = myCases.find(theFeature->getKind());
   if (aFindFeature != myCases.end()) {
-    std::map<std::string, std::pair<std::string, std::string> >::iterator
-      aFindAttr = aFindFeature->second.find(theAttribute);
-    if (aFindAttr != aFindFeature->second.end()) {
+    std::map<std::string, std::pair<std::string, std::set<std::string> > >::iterator
+      aFindAttrID = aFindFeature->second.find(theAttribute);
+    if (aFindAttrID != aFindFeature->second.end()) {
       // the the switch-attribute that contains the case value
-      AttributeStringPtr aSwitch = theFeature->string(aFindAttr->second.first);
+      AttributeStringPtr aSwitch = theFeature->string(aFindAttrID->second.first);
       if (aSwitch.get()) {
-        return aSwitch->value() == aFindAttr->second.second; // the second is the case identifier
+         // the second has the case identifier
+        return aFindAttrID->second.second.find(aSwitch->value()) != 
+               aFindAttrID->second.second.end();
       }
     }
   }