1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "Model_Validator.h"
22 #include "Model_AttributeValidator.h"
23 #include "Model_FeatureValidator.h"
25 #include <ModelAPI_Attribute.h>
26 #include <ModelAPI_AttributeString.h>
27 #include <ModelAPI_AttributeValidator.h>
28 #include <ModelAPI_Feature.h>
29 #include <ModelAPI_Result.h>
30 #include <Model_Data.h>
32 #include <Config_Translator.h>
34 #include <Events_InfoMessage.h>
36 void Model_ValidatorsFactory::registerValidator(const std::string& theID,
37 ModelAPI_Validator* theValidator)
39 if (myIDs.find(theID) != myIDs.end()) {
40 Events_InfoMessage("Model_Validator", "Validator %1 is already registered").arg(theID).send();
42 myIDs[theID] = theValidator;
46 void Model_ValidatorsFactory::assignValidator(const std::string& theID,
47 const std::string& theFeatureID)
49 if (myFeatures.find(theFeatureID) == myFeatures.end()) {
50 myFeatures[theFeatureID] = AttrValidators();
52 if (myFeatures[theFeatureID].find(theID) != myFeatures[theFeatureID].end()) {
53 //Events_Error::send(std::string("Validator ") + theID +
54 // " for feature " + theFeatureID + "is already registered");
56 myFeatures[theFeatureID][theID] = std::list<std::string>();
60 void Model_ValidatorsFactory::assignValidator(const std::string& theID,
61 const std::string& theFeatureID,
62 const std::list<std::string>& theArguments)
64 if (myFeatures.find(theFeatureID) == myFeatures.end()) {
65 myFeatures[theFeatureID] = AttrValidators();
68 if (myFeatures[theFeatureID].find(theID) != myFeatures[theFeatureID].end()) {
69 //Events_Error::send(std::string("Validator ") + theID +
70 // " for feature " + theFeatureID + "is already registered");
72 myFeatures[theFeatureID][theID] = theArguments;
76 void Model_ValidatorsFactory::assignValidator(const std::string& theID,
77 const std::string& theFeatureID,
78 const std::string& theAttrID,
79 const std::list<std::string>& theArguments)
81 // create feature-structures if not exist
82 std::map<std::string, std::map<std::string, AttrValidators> >::iterator aFeature = myAttrs.find(
84 if (aFeature == myAttrs.end()) {
85 myAttrs[theFeatureID] = std::map<std::string, AttrValidators>();
86 aFeature = myAttrs.find(theFeatureID);
88 // add attr-structure if not exist, or generate error if already exist
89 std::map<std::string, AttrValidators>::iterator anAttr = aFeature->second.find(theAttrID);
90 if (anAttr == aFeature->second.end()) {
91 aFeature->second[theAttrID] = AttrValidators();
93 aFeature->second[theAttrID][theID] = theArguments;
96 void Model_ValidatorsFactory::validators(const std::string& theFeatureID,
97 Validators& theValidators) const
99 std::map<std::string, AttrValidators>::const_iterator aFeatureIt =
100 myFeatures.find(theFeatureID);
101 if (aFeatureIt != myFeatures.cend()) {
102 AttrValidators::const_iterator aValidatorsIt = aFeatureIt->second.cbegin();
103 for (; aValidatorsIt != aFeatureIt->second.cend(); aValidatorsIt++) {
104 if (!validator(aValidatorsIt->first)) {
105 Events_InfoMessage("Model_Validator", "Validator %1 was not registered")
106 .arg(aValidatorsIt->first).send();
108 theValidators.push_back(std::make_pair(aValidatorsIt->first, aValidatorsIt->second));
112 addDefaultValidators(theValidators);
115 void Model_ValidatorsFactory::validators(const std::string& theFeatureID,
116 const std::string& theAttrID,
117 Validators& theValidators) const
119 std::map<std::string, std::map<std::string, AttrValidators> >::const_iterator aFeatureIt =
120 myAttrs.find(theFeatureID);
121 if (aFeatureIt != myAttrs.cend()) {
122 std::map<std::string, AttrValidators>::const_iterator anAttrIt =
123 aFeatureIt->second.find(theAttrID);
124 if (anAttrIt != aFeatureIt->second.end()) {
125 AttrValidators::const_iterator aValidatorsIt = anAttrIt->second.cbegin();
126 for (; aValidatorsIt != anAttrIt->second.cend(); aValidatorsIt++) {
127 if (!validator(aValidatorsIt->first)) {
128 Events_InfoMessage("Model_Validator", "Validator %1 was not registered")
129 .arg(aValidatorsIt->first).send();
131 theValidators.push_back(std::make_pair(aValidatorsIt->first, aValidatorsIt->second));
136 addDefaultAttributeValidators(theValidators);
139 Model_ValidatorsFactory::Model_ValidatorsFactory()
140 : ModelAPI_ValidatorsFactory()
142 registerValidator("Model_FeatureValidator", new Model_FeatureValidator);
143 registerValidator("Model_AttributeValidator", new Model_AttributeValidator);
146 const ModelAPI_Validator* Model_ValidatorsFactory::validator(const std::string& theID) const
148 std::map<std::string, ModelAPI_Validator*>::const_iterator aIt = myIDs.find(theID);
149 if (aIt != myIDs.end()) {
155 void Model_ValidatorsFactory::addDefaultValidators(Validators& theValidators) const
157 const static std::string kDefaultId = "Model_FeatureValidator";
158 if (!validator(kDefaultId))
160 theValidators.push_back(std::make_pair(kDefaultId, std::list<std::string>()));
163 void Model_ValidatorsFactory::addDefaultAttributeValidators(Validators& theValidators) const
165 const static std::string kDefaultId = "Model_AttributeValidator";
166 if (!validator(kDefaultId))
168 theValidators.push_back(std::make_pair(kDefaultId, std::list<std::string>()));
171 bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>& theFeature) const
173 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theFeature->data());
174 if (aData.get() && aData->isValid()) {
175 if (aData->execState() == ModelAPI_StateDone)
176 aData->eraseErrorString(); // no error => erase the information string
178 return false; // feature is broken, already not presented in the data structure
181 // check feature validators first
182 Validators aValidators;
183 validators(theFeature->getKind(), aValidators);
185 if (!aValidators.empty()) {
186 Validators::const_iterator aValidatorIt = aValidators.cbegin();
187 for(; aValidatorIt != aValidators.cend(); aValidatorIt++) {
188 const std::string& aValidatorID = aValidatorIt->first;
189 const std::list<std::string>& anArguments = aValidatorIt->second;
190 const ModelAPI_FeatureValidator* aFValidator =
191 dynamic_cast<const ModelAPI_FeatureValidator*>(validator(aValidatorID));
193 Events_InfoMessage anError;
194 if (!aFValidator->isValid(theFeature, anArguments, anError)) {
196 anError = "Unknown error.";
197 if (anError.context().empty()) {
198 anError.setContext(theFeature->getKind() + ":" + aValidatorID);
200 theFeature->setError(Config_Translator::translate(anError), false, false);
201 theFeature->data()->execState(ModelAPI_StateInvalidArgument);
208 // check all attributes for validity
209 static const std::string kAllTypes = "";
210 std::list<std::string> aLtAttributes = aData->attributesIDs(kAllTypes);
211 std::list<std::string>::const_iterator anAttrIt = aLtAttributes.cbegin();
212 for (; anAttrIt != aLtAttributes.cend(); anAttrIt++) {
213 const std::string& anAttributeID = *anAttrIt;
214 AttributePtr anAttribute = theFeature->data()->attribute(anAttributeID);
216 std::string aValidatorID;
217 Events_InfoMessage anError;
218 if (!validate(anAttribute, aValidatorID, anError)) {
220 anError = "Unknown error.";
221 if (anError.context().empty()) {
222 anError.setContext(theFeature->getKind() + ":" + anAttributeID + ":" + aValidatorID);
224 theFeature->setError(Config_Translator::translate(anError), false, false);
225 theFeature->data()->execState(ModelAPI_StateInvalidArgument);
233 bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Attribute>& theAttribute,
234 std::string& theValidator,
235 Events_InfoMessage& theError) const
237 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
238 if (!aFeature.get()) {
239 theValidator = "Model_ValidatorsFactory";
240 theError = "Attribute has no feature.";
244 // skip not-case attributes, that really may be invalid (issue 671)
245 if (!const_cast<Model_ValidatorsFactory*>(this)->isCase(aFeature, theAttribute->id()))
248 Validators aValidators;
249 validators(aFeature->getKind(), theAttribute->id(), aValidators);
251 Validators::iterator aValidatorIt = aValidators.begin();
252 for (; aValidatorIt != aValidators.end(); ++aValidatorIt) {
253 const std::string& aValidatorID = aValidatorIt->first;
254 const std::list<std::string>& anArguments = aValidatorIt->second;
255 const ModelAPI_AttributeValidator* anAttrValidator =
256 dynamic_cast<const ModelAPI_AttributeValidator*>(validator(aValidatorID));
257 if (!anAttrValidator)
259 if (!anAttrValidator->isValid(theAttribute, anArguments, theError)) {
260 theValidator = aValidatorID;
268 void Model_ValidatorsFactory::registerNotObligatory(std::string theFeature,
269 std::string theAttribute)
271 const static std::string kDefaultId = "Model_FeatureValidator";
272 std::map<std::string, ModelAPI_Validator*>::const_iterator it = myIDs.find(kDefaultId);
273 if (it != myIDs.end()) {
274 Model_FeatureValidator* aValidator = dynamic_cast<Model_FeatureValidator*>(it->second);
276 aValidator->registerNotObligatory(theFeature, theAttribute);
281 bool Model_ValidatorsFactory::isNotObligatory(std::string theFeature, std::string theAttribute)
283 const static std::string kDefaultId = "Model_FeatureValidator";
284 std::map<std::string, ModelAPI_Validator*>::const_iterator it = myIDs.find(kDefaultId);
285 if (it != myIDs.end()) {
286 Model_FeatureValidator* aValidator = dynamic_cast<Model_FeatureValidator*>(it->second);
288 return aValidator->isNotObligatory(theFeature, theAttribute);
291 return false; // default
294 void Model_ValidatorsFactory::registerConcealment(std::string theFeature, std::string theAttribute)
296 std::map<std::string, std::set<std::string> >::iterator aFind = myConcealed.find(theFeature);
297 if (aFind == myConcealed.end()) {
298 std::set<std::string> aNewSet;
299 aNewSet.insert(theAttribute);
300 myConcealed[theFeature] = aNewSet;
302 aFind->second.insert(theAttribute);
306 bool Model_ValidatorsFactory::isConcealed(std::string theFeature, std::string theAttribute)
308 std::map<std::string, std::set<std::string> >::iterator aFind = myConcealed.find(theFeature);
309 return aFind != myConcealed.end() && aFind->second.find(theAttribute) != aFind->second.end();
312 void Model_ValidatorsFactory::registerCase(std::string theFeature, std::string theAttribute,
313 const std::list<std::pair<std::string, std::string> >& theCases)
315 std::map<std::string, std::map<std::string, std::map<std::string, std::set<std::string> > > >
316 ::iterator aFindFeature = myCases.find(theFeature);
317 if (aFindFeature == myCases.end()) {
318 myCases[theFeature] = std::map<std::string, std::map<std::string, std::set<std::string> > >();
319 aFindFeature = myCases.find(theFeature);
321 std::map<std::string, std::map<std::string, std::set<std::string> > >::iterator aFindAttrID =
322 aFindFeature->second.find(theAttribute);
324 if (aFindAttrID == aFindFeature->second.end()) {
325 aFindFeature->second[theAttribute] =
326 std::map<std::string, std::set<std::string> >();
327 aFindAttrID = aFindFeature->second.find(theAttribute);
329 std::list<std::pair<std::string, std::string> >::const_iterator aCasesIt = theCases.begin(),
330 aCasesLast = theCases.end();
331 std::map<std::string, std::set<std::string> > aFindCases = aFindAttrID->second;
332 for (; aCasesIt != aCasesLast; aCasesIt++) {
333 std::pair<std::string, std::string> aCasePair = *aCasesIt;
334 std::string aSwitch = aCasePair.first;
335 if (aFindAttrID->second.find(aSwitch) == aFindAttrID->second.end()) {
336 aFindAttrID->second[aSwitch] = std::set<std::string>();
338 aFindAttrID->second[aSwitch].insert(aCasePair.second);
342 bool Model_ValidatorsFactory::isCase(FeaturePtr theFeature, std::string theAttribute)
344 bool anInCase = true;
345 std::map<std::string, std::map<std::string, std::map<std::string, std::set<std::string> > > >
346 ::iterator aFindFeature = myCases.find(theFeature->getKind());
347 if (aFindFeature != myCases.end()) {
348 std::map<std::string, std::map<std::string, std::set<std::string> > >::iterator
349 aFindAttrID = aFindFeature->second.find(theAttribute);
350 if (aFindAttrID != aFindFeature->second.end()) {
351 std::map<std::string, std::set<std::string> >::iterator
352 aCasesIt = aFindAttrID->second.begin(), aCasesLast = aFindAttrID->second.end();
353 for (; aCasesIt != aCasesLast && anInCase; aCasesIt++) {
354 // the the switch-attribute that contains the case value
355 AttributeStringPtr aSwitch = theFeature->string(aCasesIt->first);
357 // the second has the case identifier
358 anInCase = aCasesIt->second.find(aSwitch->value()) != aCasesIt->second.end();
363 return anInCase; // if no additional conditions, this attribute is the case to be validated
366 void Model_ValidatorsFactory::registerMainArgument(std::string theFeature,
367 std::string theAttribute)
369 std::map<std::string, std::string>::iterator aFound = myMainArgument.find(theFeature);
370 if (aFound == myMainArgument.end())
371 myMainArgument[theFeature] = theAttribute;
374 bool Model_ValidatorsFactory::isMainArgument(std::string theFeature, std::string theAttribute)
376 std::map<std::string, std::string>::iterator aFound = myMainArgument.find(theFeature);
377 return aFound != myMainArgument.end() && aFound->second == theAttribute;
380 void Model_ValidatorsFactory::registerGeometricalSelection(std::string theFeature,
381 std::string theAttribute)
383 std::map<std::string, std::set<std::string> >::iterator aFind =
384 myGeometricalSelection.find(theFeature);
385 if (aFind == myGeometricalSelection.end()) {
386 std::set<std::string> aNewSet;
387 aNewSet.insert(theAttribute);
388 myGeometricalSelection[theFeature] = aNewSet;
391 aFind->second.insert(theAttribute);
395 bool Model_ValidatorsFactory::isGeometricalSelection(std::string theFeature,
396 std::string theAttribute)
398 std::map<std::string, std::set<std::string> >::iterator aFind =
399 myGeometricalSelection.find(theFeature);
400 return aFind != myGeometricalSelection.end()
401 && aFind->second.find(theAttribute) != aFind->second.end();