From 8cac8d7c1b08cb25f02cd60e953ce1656dd2a3a6 Mon Sep 17 00:00:00 2001 From: spo Date: Wed, 5 Aug 2015 17:49:17 +0300 Subject: [PATCH] Error management -- Default attribute validator --- src/Model/CMakeLists.txt | 2 + src/Model/Model_AttributeValidator.cpp | 56 ++++++ src/Model/Model_AttributeValidator.h | 31 ++++ src/Model/Model_Validator.cpp | 29 ++- src/Model/Model_Validator.h | 2 + .../ParametersPlugin_EvalListener.cpp | 167 ++++++++---------- 6 files changed, 189 insertions(+), 98 deletions(-) create mode 100644 src/Model/Model_AttributeValidator.cpp create mode 100644 src/Model/Model_AttributeValidator.h diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 36eb50535..35440629e 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -32,6 +32,7 @@ SET(PROJECT_HEADERS Model_ResultGroup.h Model_ResultParameter.h Model_FeatureValidator.h + Model_AttributeValidator.h ) SET(PROJECT_SOURCES @@ -63,6 +64,7 @@ SET(PROJECT_SOURCES Model_ResultGroup.cpp Model_ResultParameter.cpp Model_FeatureValidator.cpp + Model_AttributeValidator.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/Model/Model_AttributeValidator.cpp b/src/Model/Model_AttributeValidator.cpp new file mode 100644 index 000000000..9a6c95465 --- /dev/null +++ b/src/Model/Model_AttributeValidator.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: Model_AttributeValidator.cpp +// Created: 29 July 2015 +// Author: Sergey POKHODENKO + +#include "Model_AttributeValidator.h" +#include +#include +#include + +bool Model_AttributeValidator::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const +{ + if (theAttribute->attributeType() == ModelAPI_AttributeDouble::typeId()) { + AttributeDoublePtr anAttribue = + std::dynamic_pointer_cast(theAttribute); + if (!anAttribue->expressionError().empty()) { + theError = anAttribue->expressionError(); + return false; + } + } else + if (theAttribute->attributeType() == GeomDataAPI_Point::typeId()) { + AttributePointPtr anAttribue = + std::dynamic_pointer_cast(theAttribute); + + const char* aComponent[] = {"X", "Y", "Z"}; + std::string anErrorMessage; + for (int i = 0; i < 3; ++i) { + if (!anAttribue->expressionError(i).empty()) + anErrorMessage.append("\n").append(aComponent[i]).append(": ").append(anAttribue->expressionError(i)); + } + if (!anErrorMessage.empty()) { + theError = anErrorMessage; + return false; + } + } else + if (theAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) { + AttributePoint2DPtr anAttribue = + std::dynamic_pointer_cast(theAttribute); + + const char* aComponent[] = {"X", "Y"}; + std::string anErrorMessage; + for (int i = 0; i < 2; ++i) { + if (!anAttribue->expressionError(i).empty()) + anErrorMessage.append("\n").append(aComponent[i]).append(": ").append(anAttribue->expressionError(i)); + } + if (!anErrorMessage.empty()) { + theError = anErrorMessage; + return false; + } + } + return true; +} + diff --git a/src/Model/Model_AttributeValidator.h b/src/Model/Model_AttributeValidator.h new file mode 100644 index 000000000..eea6cda4b --- /dev/null +++ b/src/Model/Model_AttributeValidator.h @@ -0,0 +1,31 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: ModelAPI_AttributeValidator.h +// Created: 29 July 2015 +// Author: Sergey POKHODENKO + +#ifndef Model_AttributeValidator_H +#define Model_AttributeValidator_H + +#include "Model.h" +#include + +/**\class Model_AttributeValidator + * \ingroup DataModel + * \brief The geneneric validator for the attribute. + * + * Can be redefined for some specific attributes, but by default for each attribute this validator is + * used: it checks the argument and if it contains invalid expression the attribute is invalid. + */ +class Model_AttributeValidator : public ModelAPI_AttributeValidator +{ +public: + /// \param theAttribute the checked attribute + /// \param theArguments arguments of the attribute + /// \returns true if attribute is valid + MODEL_EXPORT virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const; +}; + +#endif // Model_AttributeValidator_H diff --git a/src/Model/Model_Validator.cpp b/src/Model/Model_Validator.cpp index 83a4e04cb..621f33b5f 100644 --- a/src/Model/Model_Validator.cpp +++ b/src/Model/Model_Validator.cpp @@ -4,13 +4,17 @@ // Created: 2 Jul 2014 // Author: Mikhail PONIKAROV -#include -#include -#include +#include "Model_Validator.h" + +#include "Model_AttributeValidator.h" +#include "Model_FeatureValidator.h" + #include -#include -#include #include +#include +#include +#include + #include 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,10 +140,16 @@ void Model_ValidatorsFactory::addDefaultValidators(Validators& theValidators) co theValidators.push_back(std::make_pair(kDefaultId, std::list())); } -bool Model_ValidatorsFactory::validate(const std::shared_ptr& 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())); +} +bool Model_ValidatorsFactory::validate(const std::shared_ptr& theFeature) const +{ ModelAPI_ExecState anExecState = theFeature->data()->execState(); theFeature->setError("", false); theFeature->data()->execState(anExecState); diff --git a/src/Model/Model_Validator.h b/src/Model/Model_Validator.h index 87552dd42..3156a17de 100644 --- a/src/Model/Model_Validator.h +++ b/src/Model/Model_Validator.h @@ -104,6 +104,8 @@ class Model_ValidatorsFactory : public ModelAPI_ValidatorsFactory protected: /// Adds the defualt validators that are usefull for all features. void addDefaultValidators(Validators& theValidators) const; + /// Adds the defualt validators that are usefull for all attributes. + void addDefaultAttributeValidators(Validators& theValidators) const; /// Get instance from Session Model_ValidatorsFactory(); diff --git a/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp b/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp index bb0bc5ba3..9d86a0fc7 100644 --- a/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp +++ b/src/ParametersPlugin/ParametersPlugin_EvalListener.cpp @@ -90,66 +90,63 @@ void ParametersPlugin_EvalListener::processEvaluationEvent( std::shared_ptr aMessage = std::dynamic_pointer_cast(theMessage); - // Double - AttributeDoublePtr aDoubleAttribute = - std::dynamic_pointer_cast(aMessage->attribute()); - if (aDoubleAttribute.get()) { + if (aMessage->attribute()->attributeType() == ModelAPI_AttributeDouble::typeId()) { + AttributeDoublePtr anAttribute = + std::dynamic_pointer_cast(aMessage->attribute()); std::string anError; - double aValue = evaluate(aDoubleAttribute->text(), anError); - if (anError.empty()) { - aDoubleAttribute->setCalculatedValue(aValue); - aDoubleAttribute->setExpressionInvalid(false); - } else { // set feature as invalid-parameter arguments - aDoubleAttribute->setExpressionInvalid(true); - } - } - - // Point - AttributePointPtr aPointAttribute = - std::dynamic_pointer_cast(aMessage->attribute()); - if (aPointAttribute.get()) { - std::string anError[3]; - double aValue[3] = { - evaluate(aPointAttribute->textX(), anError[0]), - evaluate(aPointAttribute->textY(), anError[1]), - evaluate(aPointAttribute->textZ(), anError[2]) + double aValue = evaluate(anAttribute->text(), anError); + bool isValid = anError.empty(); + if (isValid) + anAttribute->setCalculatedValue(aValue); + anAttribute->setExpressionInvalid(!isValid); + anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError); + } else + if (aMessage->attribute()->attributeType() == GeomDataAPI_Point::typeId()) { + AttributePointPtr anAttribute = + std::dynamic_pointer_cast(aMessage->attribute()); + std::string aText[] = { + anAttribute->textX(), + anAttribute->textY(), + anAttribute->textZ() }; - bool isValid[3] = { - anError[0].empty(), - anError[1].empty(), - anError[2].empty() + double aCalculatedValue[] = { + anAttribute->x(), + anAttribute->y(), + anAttribute->z() }; - aPointAttribute->setExpressionInvalid(0, !isValid[0]); - aPointAttribute->setExpressionInvalid(1, !isValid[1]); - aPointAttribute->setExpressionInvalid(2, !isValid[2]); - - aPointAttribute->setCalculatedValue( - isValid[0] ? aValue[0] : aPointAttribute->x(), - isValid[1] ? aValue[1] : aPointAttribute->y(), - isValid[2] ? aValue[2] : aPointAttribute->z() - ); - } - - // Point2D - AttributePoint2DPtr aPoint2DAttribute = - std::dynamic_pointer_cast(aMessage->attribute()); - if (aPoint2DAttribute.get()) { - std::string anError[2]; - double aValue[2] = { - evaluate(aPoint2DAttribute->textX(), anError[0]), - evaluate(aPoint2DAttribute->textY(), anError[1]) + for (int i = 0; i < 3; ++i) { + std::string anError; + double aValue = evaluate(aText[i], anError); + bool isValid = anError.empty(); + if (isValid) aCalculatedValue[i] = aValue; + anAttribute->setExpressionInvalid(i, !isValid); + anAttribute->setExpressionError(i, aText[i].empty() ? "" : anError); + } + anAttribute->setCalculatedValue(aCalculatedValue[0], + aCalculatedValue[1], + aCalculatedValue[2]); + } else + if (aMessage->attribute()->attributeType() == GeomDataAPI_Point2D::typeId()) { + AttributePoint2DPtr anAttribute = + std::dynamic_pointer_cast(aMessage->attribute()); + std::string aText[] = { + anAttribute->textX(), + anAttribute->textY() }; - bool isValid[2] = { - anError[0].empty(), - anError[1].empty() + double aCalculatedValue[] = { + anAttribute->x(), + anAttribute->y() }; - aPoint2DAttribute->setExpressionInvalid(0, !isValid[0]); - aPoint2DAttribute->setExpressionInvalid(1, !isValid[1]); - - aPoint2DAttribute->setCalculatedValue( - isValid[0] ? aValue[0] : aPoint2DAttribute->x(), - isValid[1] ? aValue[1] : aPoint2DAttribute->y() - ); + for (int i = 0; i < 2; ++i) { + std::string anError; + double aValue = evaluate(aText[i], anError); + bool isValid = anError.empty(); + if (isValid) aCalculatedValue[i] = aValue; + anAttribute->setExpressionInvalid(i, !isValid); + anAttribute->setExpressionError(i, aText[i].empty() ? "" : anError); + } + anAttribute->setCalculatedValue(aCalculatedValue[0], + aCalculatedValue[1]); } } @@ -215,49 +212,41 @@ void ParametersPlugin_EvalListener::renameInAttribute( const std::string& theOldName, const std::string& theNewName) { - // Double - AttributeDoublePtr aDoubleAttribute = - std::dynamic_pointer_cast(theAttribute); - if (aDoubleAttribute.get()) { - std::string anExpressionString = aDoubleAttribute->text(); + if (theAttribute->attributeType() == ModelAPI_AttributeDouble::typeId()) { + AttributeDoublePtr anAttribute = + std::dynamic_pointer_cast(theAttribute); + std::string anExpressionString = anAttribute->text(); anExpressionString = renameInPythonExpression(anExpressionString, - theOldName, - theNewName); - aDoubleAttribute->setText(anExpressionString); - } - - // Point - AttributePointPtr aPointAttribute = - std::dynamic_pointer_cast(theAttribute); - if (aPointAttribute.get()) { + theOldName, theNewName); + anAttribute->setText(anExpressionString); + } else + if (theAttribute->attributeType() == GeomDataAPI_Point::typeId()) { + AttributePointPtr anAttribute = + std::dynamic_pointer_cast(theAttribute); std::string anExpressionString[3] = { - aPointAttribute->textX(), - aPointAttribute->textY(), - aPointAttribute->textZ() + anAttribute->textX(), + anAttribute->textY(), + anAttribute->textZ() }; for (int i = 0; i < 3; ++i) anExpressionString[i] = renameInPythonExpression(anExpressionString[i], - theOldName, - theNewName); - aPointAttribute->setText(anExpressionString[0], - anExpressionString[1], - anExpressionString[2]); - } - - // Point2D - AttributePoint2DPtr aPoint2DAttribute = - std::dynamic_pointer_cast(theAttribute); - if (aPoint2DAttribute.get()) { + theOldName, theNewName); + anAttribute->setText(anExpressionString[0], + anExpressionString[1], + anExpressionString[2]); + } else + if (theAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) { + AttributePoint2DPtr anAttribute = + std::dynamic_pointer_cast(theAttribute); std::string anExpressionString[2] = { - aPoint2DAttribute->textX(), - aPoint2DAttribute->textY() + anAttribute->textX(), + anAttribute->textY() }; for (int i = 0; i < 2; ++i) anExpressionString[i] = renameInPythonExpression(anExpressionString[i], - theOldName, - theNewName); - aPoint2DAttribute->setText(anExpressionString[0], - anExpressionString[1]); + theOldName, theNewName); + anAttribute->setText(anExpressionString[0], + anExpressionString[1]); } } -- 2.39.2