1 // Copyright (C) 2014-2017 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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "Model_Validator.h"
23 #include "Model_AttributeValidator.h"
24 #include "Model_FeatureValidator.h"
26 #include <ModelAPI_Attribute.h>
27 #include <ModelAPI_AttributeString.h>
28 #include <ModelAPI_AttributeValidator.h>
29 #include <ModelAPI_Feature.h>
30 #include <ModelAPI_Result.h>
31 #include <Model_Data.h>
33 #include <Config_Translator.h>
35 #include <Events_InfoMessage.h>
37 void Model_ValidatorsFactory::registerValidator(const std::string& theID,
38 ModelAPI_Validator* theValidator)
40 if (myIDs.find(theID) != myIDs.end()) {
41 Events_InfoMessage("Model_Validator", "Validator %1 is already registered").arg(theID).send();
43 myIDs[theID] = theValidator;
47 void Model_ValidatorsFactory::assignValidator(const std::string& theID,
48 const std::string& theFeatureID)
50 if (myFeatures.find(theFeatureID) == myFeatures.end()) {
51 myFeatures[theFeatureID] = AttrValidators();
53 if (myFeatures[theFeatureID].find(theID) != myFeatures[theFeatureID].end()) {
54 //Events_Error::send(std::string("Validator ") + theID +
55 // " for feature " + theFeatureID + "is already registered");
57 myFeatures[theFeatureID][theID] = std::list<std::string>();
61 void Model_ValidatorsFactory::assignValidator(const std::string& theID,
62 const std::string& theFeatureID,
63 const std::list<std::string>& theArguments)
65 if (myFeatures.find(theFeatureID) == myFeatures.end()) {
66 myFeatures[theFeatureID] = AttrValidators();
69 if (myFeatures[theFeatureID].find(theID) != myFeatures[theFeatureID].end()) {
70 //Events_Error::send(std::string("Validator ") + theID +
71 // " for feature " + theFeatureID + "is already registered");
73 myFeatures[theFeatureID][theID] = theArguments;
77 void Model_ValidatorsFactory::assignValidator(const std::string& theID,
78 const std::string& theFeatureID,
79 const std::string& theAttrID,
80 const std::list<std::string>& theArguments)
82 // create feature-structures if not exist
83 std::map<std::string, std::map<std::string, AttrValidators> >::iterator aFeature = myAttrs.find(
85 if (aFeature == myAttrs.end()) {
86 myAttrs[theFeatureID] = std::map<std::string, AttrValidators>();
87 aFeature = myAttrs.find(theFeatureID);
89 // add attr-structure if not exist, or generate error if already exist
90 std::map<std::string, AttrValidators>::iterator anAttr = aFeature->second.find(theAttrID);
91 if (anAttr == aFeature->second.end()) {
92 aFeature->second[theAttrID] = AttrValidators();
94 aFeature->second[theAttrID][theID] = theArguments;
97 void Model_ValidatorsFactory::validators(const std::string& theFeatureID,
98 Validators& theValidators) const
100 std::map<std::string, AttrValidators>::const_iterator aFeatureIt =
101 myFeatures.find(theFeatureID);
102 if (aFeatureIt != myFeatures.cend()) {
103 AttrValidators::const_iterator aValidatorsIt = aFeatureIt->second.cbegin();
104 for (; aValidatorsIt != aFeatureIt->second.cend(); aValidatorsIt++) {
105 if (!validator(aValidatorsIt->first)) {
106 Events_InfoMessage("Model_Validator", "Validator %1 was not registered")
107 .arg(aValidatorsIt->first).send();
109 theValidators.push_back(std::make_pair(aValidatorsIt->first, aValidatorsIt->second));
113 addDefaultValidators(theValidators);
116 void Model_ValidatorsFactory::validators(const std::string& theFeatureID,
117 const std::string& theAttrID,
118 Validators& theValidators) const
120 std::map<std::string, std::map<std::string, AttrValidators> >::const_iterator aFeatureIt =
121 myAttrs.find(theFeatureID);
122 if (aFeatureIt != myAttrs.cend()) {
123 std::map<std::string, AttrValidators>::const_iterator anAttrIt =
124 aFeatureIt->second.find(theAttrID);
125 if (anAttrIt != aFeatureIt->second.end()) {
126 AttrValidators::const_iterator aValidatorsIt = anAttrIt->second.cbegin();
127 for (; aValidatorsIt != anAttrIt->second.cend(); aValidatorsIt++) {
128 if (!validator(aValidatorsIt->first)) {
129 Events_InfoMessage("Model_Validator", "Validator %1 was not registered")
130 .arg(aValidatorsIt->first).send();
132 theValidators.push_back(std::make_pair(aValidatorsIt->first, aValidatorsIt->second));
137 addDefaultAttributeValidators(theValidators);
140 Model_ValidatorsFactory::Model_ValidatorsFactory()
141 : ModelAPI_ValidatorsFactory()
143 registerValidator("Model_FeatureValidator", new Model_FeatureValidator);
144 registerValidator("Model_AttributeValidator", new Model_AttributeValidator);
147 const ModelAPI_Validator* Model_ValidatorsFactory::validator(const std::string& theID) const
149 std::map<std::string, ModelAPI_Validator*>::const_iterator aIt = myIDs.find(theID);
150 if (aIt != myIDs.end()) {
156 void Model_ValidatorsFactory::addDefaultValidators(Validators& theValidators) const
158 const static std::string kDefaultId = "Model_FeatureValidator";
159 if (!validator(kDefaultId))
161 theValidators.push_back(std::make_pair(kDefaultId, std::list<std::string>()));
164 void Model_ValidatorsFactory::addDefaultAttributeValidators(Validators& theValidators) const
166 const static std::string kDefaultId = "Model_AttributeValidator";
167 if (!validator(kDefaultId))
169 theValidators.push_back(std::make_pair(kDefaultId, std::list<std::string>()));
172 bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Feature>& theFeature) const
174 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theFeature->data());
175 if (aData.get() && aData->isValid()) {
176 if (aData->execState() == ModelAPI_StateDone)
177 aData->eraseErrorString(); // no error => erase the information string
179 return false; // feature is broken, already not presented in the data structure
182 // check feature validators first
183 Validators aValidators;
184 validators(theFeature->getKind(), aValidators);
186 if (!aValidators.empty()) {
187 Validators::const_iterator aValidatorIt = aValidators.cbegin();
188 for(; aValidatorIt != aValidators.cend(); aValidatorIt++) {
189 const std::string& aValidatorID = aValidatorIt->first;
190 const std::list<std::string>& anArguments = aValidatorIt->second;
191 const ModelAPI_FeatureValidator* aFValidator =
192 dynamic_cast<const ModelAPI_FeatureValidator*>(validator(aValidatorID));
194 Events_InfoMessage anError;
195 if (!aFValidator->isValid(theFeature, anArguments, anError)) {
197 anError = "Unknown error.";
198 if (anError.context().empty()) {
199 anError.setContext(theFeature->getKind() + ":" + aValidatorID);
201 theFeature->setError(Config_Translator::translate(anError), false, false);
202 theFeature->data()->execState(ModelAPI_StateInvalidArgument);
209 // check all attributes for validity
210 static const std::string kAllTypes = "";
211 std::list<std::string> aLtAttributes = aData->attributesIDs(kAllTypes);
212 std::list<std::string>::const_iterator anAttrIt = aLtAttributes.cbegin();
213 for (; anAttrIt != aLtAttributes.cend(); anAttrIt++) {
214 const std::string& anAttributeID = *anAttrIt;
215 AttributePtr anAttribute = theFeature->data()->attribute(anAttributeID);
217 std::string aValidatorID;
218 Events_InfoMessage anError;
219 if (!validate(anAttribute, aValidatorID, anError)) {
221 anError = "Unknown error.";
222 if (anError.context().empty()) {
223 anError.setContext(theFeature->getKind() + ":" + anAttributeID + ":" + aValidatorID);
225 theFeature->setError(Config_Translator::translate(anError), false, false);
226 theFeature->data()->execState(ModelAPI_StateInvalidArgument);
234 bool Model_ValidatorsFactory::validate(const std::shared_ptr<ModelAPI_Attribute>& theAttribute,
235 std::string& theValidator,
236 Events_InfoMessage& theError) const
238 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
239 if (!aFeature.get()) {
240 theValidator = "Model_ValidatorsFactory";
241 theError = "Attribute has no feature.";
245 // skip not-case attributes, that really may be invalid (issue 671)
246 if (!const_cast<Model_ValidatorsFactory*>(this)->isCase(aFeature, theAttribute->id()))
249 Validators aValidators;
250 validators(aFeature->getKind(), theAttribute->id(), aValidators);
252 Validators::iterator aValidatorIt = aValidators.begin();
253 for (; aValidatorIt != aValidators.end(); ++aValidatorIt) {
254 const std::string& aValidatorID = aValidatorIt->first;
255 const std::list<std::string>& anArguments = aValidatorIt->second;
256 const ModelAPI_AttributeValidator* anAttrValidator =
257 dynamic_cast<const ModelAPI_AttributeValidator*>(validator(aValidatorID));
258 if (!anAttrValidator)
260 if (!anAttrValidator->isValid(theAttribute, anArguments, theError)) {
261 theValidator = aValidatorID;
269 void Model_ValidatorsFactory::registerNotObligatory(std::string theFeature,
270 std::string theAttribute)
272 const static std::string kDefaultId = "Model_FeatureValidator";
273 std::map<std::string, ModelAPI_Validator*>::const_iterator it = myIDs.find(kDefaultId);
274 if (it != myIDs.end()) {
275 Model_FeatureValidator* aValidator = dynamic_cast<Model_FeatureValidator*>(it->second);
277 aValidator->registerNotObligatory(theFeature, theAttribute);
282 bool Model_ValidatorsFactory::isNotObligatory(std::string theFeature, std::string theAttribute)
284 const static std::string kDefaultId = "Model_FeatureValidator";
285 std::map<std::string, ModelAPI_Validator*>::const_iterator it = myIDs.find(kDefaultId);
286 if (it != myIDs.end()) {
287 Model_FeatureValidator* aValidator = dynamic_cast<Model_FeatureValidator*>(it->second);
289 return aValidator->isNotObligatory(theFeature, theAttribute);
292 return false; // default
295 void Model_ValidatorsFactory::registerConcealment(std::string theFeature, std::string theAttribute)
297 std::map<std::string, std::set<std::string> >::iterator aFind = myConcealed.find(theFeature);
298 if (aFind == myConcealed.end()) {
299 std::set<std::string> aNewSet;
300 aNewSet.insert(theAttribute);
301 myConcealed[theFeature] = aNewSet;
303 aFind->second.insert(theAttribute);
307 bool Model_ValidatorsFactory::isConcealed(std::string theFeature, std::string theAttribute)
309 std::map<std::string, std::set<std::string> >::iterator aFind = myConcealed.find(theFeature);
310 return aFind != myConcealed.end() && aFind->second.find(theAttribute) != aFind->second.end();
313 void Model_ValidatorsFactory::registerCase(std::string theFeature, std::string theAttribute,
314 const std::list<std::pair<std::string, std::string> >& theCases)
316 std::map<std::string, std::map<std::string, std::map<std::string, std::set<std::string> > > >
317 ::iterator aFindFeature = myCases.find(theFeature);
318 if (aFindFeature == myCases.end()) {
319 myCases[theFeature] = std::map<std::string, std::map<std::string, std::set<std::string> > >();
320 aFindFeature = myCases.find(theFeature);
322 std::map<std::string, std::map<std::string, std::set<std::string> > >::iterator aFindAttrID =
323 aFindFeature->second.find(theAttribute);
325 if (aFindAttrID == aFindFeature->second.end()) {
326 aFindFeature->second[theAttribute] =
327 std::map<std::string, std::set<std::string> >();
328 aFindAttrID = aFindFeature->second.find(theAttribute);
330 std::list<std::pair<std::string, std::string> >::const_iterator aCasesIt = theCases.begin(),
331 aCasesLast = theCases.end();
332 std::map<std::string, std::set<std::string> > aFindCases = aFindAttrID->second;
333 for (; aCasesIt != aCasesLast; aCasesIt++) {
334 std::pair<std::string, std::string> aCasePair = *aCasesIt;
335 std::string aSwitch = aCasePair.first;
336 if (aFindAttrID->second.find(aSwitch) == aFindAttrID->second.end()) {
337 aFindAttrID->second[aSwitch] = std::set<std::string>();
339 aFindAttrID->second[aSwitch].insert(aCasePair.second);
343 bool Model_ValidatorsFactory::isCase(FeaturePtr theFeature, std::string theAttribute)
345 bool anInCase = true;
346 std::map<std::string, std::map<std::string, std::map<std::string, std::set<std::string> > > >
347 ::iterator aFindFeature = myCases.find(theFeature->getKind());
348 if (aFindFeature != myCases.end()) {
349 std::map<std::string, std::map<std::string, std::set<std::string> > >::iterator
350 aFindAttrID = aFindFeature->second.find(theAttribute);
351 if (aFindAttrID != aFindFeature->second.end()) {
352 std::map<std::string, std::set<std::string> >::iterator
353 aCasesIt = aFindAttrID->second.begin(), aCasesLast = aFindAttrID->second.end();
354 for (; aCasesIt != aCasesLast && anInCase; aCasesIt++) {
355 // the the switch-attribute that contains the case value
356 AttributeStringPtr aSwitch = theFeature->string(aCasesIt->first);
358 // the second has the case identifier
359 anInCase = aCasesIt->second.find(aSwitch->value()) != aCasesIt->second.end();
364 return anInCase; // if no additional conditions, this attribute is the case to be validated
367 void Model_ValidatorsFactory::registerMainArgument(std::string theFeature,
368 std::string theAttribute)
370 std::map<std::string, std::string>::iterator aFound = myMainArgument.find(theFeature);
371 if (aFound == myMainArgument.end())
372 myMainArgument[theFeature] = theAttribute;
375 bool Model_ValidatorsFactory::isMainArgument(std::string theFeature, std::string theAttribute)
377 std::map<std::string, std::string>::iterator aFound = myMainArgument.find(theFeature);
378 return aFound != myMainArgument.end() && aFound->second == theAttribute;
381 void Model_ValidatorsFactory::registerGeometricalSelection(std::string theFeature,
382 std::string theAttribute)
384 std::map<std::string, std::set<std::string> >::iterator aFind =
385 myGeometricalSelection.find(theFeature);
386 if (aFind == myGeometricalSelection.end()) {
387 std::set<std::string> aNewSet;
388 aNewSet.insert(theAttribute);
389 myGeometricalSelection[theFeature] = aNewSet;
392 aFind->second.insert(theAttribute);
396 bool Model_ValidatorsFactory::isGeometricalSelection(std::string theFeature,
397 std::string theAttribute)
399 std::map<std::string, std::set<std::string> >::iterator aFind =
400 myGeometricalSelection.find(theFeature);
401 return aFind != myGeometricalSelection.end()
402 && aFind->second.find(theAttribute) != aFind->second.end();