fw4spl
IActivityValidator.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2016.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwActivities/IActivityValidator.hpp"
8 #include "fwActivities/IObjectValidator.hpp"
9 
10 #include <fwData/Composite.hpp>
11 #include <fwData/Vector.hpp>
12 
13 #include <fwDataCamp/getObject.hpp>
14 
15 #include <fwMedData/ActivitySeries.hpp>
16 
17 
18 namespace fwActivities
19 {
20 
21 //------------------------------------------------------------------------------
22 
23 IValidator::ValidationType IActivityValidator::checkRequirements(const ::fwMedData::ActivitySeries::csptr &activity)
24 const
25 {
26  IValidator::ValidationType validation;
27  validation.first = true;
28  validation.second = "";
29 
31  info = ::fwActivities::registry::Activities::getDefault()->getInfo(activity->getActivityConfigId());
32 
33  ::fwData::Composite::sptr composite = activity->getData();
34 
35  for (::fwActivities::registry::ActivityRequirement req: info.requirements)
36  {
37  if ((req.minOccurs == 1 && req.maxOccurs == 1) ||
38  (req.minOccurs == 0 && req.maxOccurs == 0) ||
39  req.create) // One object is required
40  {
41  ::fwData::Object::sptr obj = composite->at< ::fwData::Object >(req.name);
42  if (!obj)
43  {
44  validation.first = false;
45  validation.second += "\n - The parameter '" + req.name + "' is required but is not defined.";
46  }
47  else if (obj->getClassname() != req.type)
48  {
49  validation.first = false;
50  validation.second += "\n - The parameter '" + req.name + "' must be a '" + req.type + "'.";
51  }
52  else
53  {
54  IValidator::ValidationType val = this->checkObject(obj, req.validator);
55  if (!val.first)
56  {
57  validation.first = false;
58  validation.second += "\n - The parameter '" + req.name + "' is not valid: " + val.second;
59  }
60  }
61  }
62  else if (req.container == "vector")
63  {
64  ::fwData::Vector::sptr vector = composite->at< ::fwData::Vector >(req.name);
65  if (!vector)
66  {
67  validation.first = false;
68  validation.second += "\n - The parameter '" + req.name + "' must be a Vector of '" + req.type + "'.";
69  }
70  else
71  {
72  unsigned int nbObj = static_cast<unsigned int >(vector->size());
73  if (nbObj < req.minOccurs)
74  {
75  validation.first = false;
76  validation.second += "\n - The parameter '" + req.name + "' must contain at least " +
77  std::to_string(req.minOccurs) + " objects.";
78  }
79  else if (nbObj > req.maxOccurs)
80  {
81  validation.first = false;
82  validation.second += "\n - The parameter '" + req.name + "' must contain at most " +
83  std::to_string(req.maxOccurs) + " objects.";
84  }
85  else
86  {
87  bool isValid = true;
88  for (::fwData::Object::sptr obj : *vector)
89  {
90  if (!obj)
91  {
92  validation.first = false;
93  validation.second += "\n - The parameter '" + req.name +
94  "' must contain valid objects of type '" + req.type + "'.";
95  isValid = false;
96  }
97  if (obj->getClassname() != req.type)
98  {
99  validation.first = false;
100  validation.second += "\n - The parameter '" + req.name +
101  "' must contain only objects of type '" + req.type + "'.";
102  isValid = false;
103  }
104  }
105  if (isValid)
106  {
107  IValidator::ValidationType val = this->checkObject(vector, req.validator);
108  if (!val.first)
109  {
110  validation.first = false;
111  validation.second += "\n - The parameter '" + req.name + "' is not valid: " + val.second;
112  }
113  }
114  }
115  }
116  }
117  else // container == composite
118  {
119  ::fwData::Composite::sptr currentComposite = composite->at< ::fwData::Composite >(req.name);
120  if (!currentComposite)
121  {
122  validation.first = false;
123  validation.second += "\n - The parameter '" + req.name + "' must be a Composite of '" +
124  req.type + "'.";
125  }
126  else
127  {
128  unsigned int nbObj = static_cast<unsigned int>(currentComposite->size());
129  if (nbObj < req.minOccurs)
130  {
131  validation.first = false;
132  validation.second += "\n - The parameter '" + req.name + "' must contain at least " +
133  std::to_string(req.minOccurs) + " objects.";
134  }
135  else if (nbObj > req.maxOccurs)
136  {
137  validation.first = false;
138  validation.second += "\n - The parameter '" + req.name + "' must contain at most " +
139  std::to_string(req.minOccurs) + " objects.";
140  }
141  else
142  {
143  bool isValid = true;
144 
145  for (auto elt : *currentComposite)
146  {
147  std::string key = elt.first;
148  ::fwData::Object::sptr obj = elt.second;
150  bool keyIsFound = false;
152  {
153  if (key == keyElt.key)
154  {
155  reqKey = keyElt;
156  keyIsFound = true;
157  }
158  }
159  if (!keyIsFound)
160  {
161  validation.first = false;
162  validation.second += "\n - The parameter '" + req.name +
163  "' has an invalid key : '" + key + "'.";
164  isValid = false;
165 
166  }
167  else if (!obj)
168  {
169  validation.first = false;
170  validation.second += "\n - The parameter '" + req.name +
171  "' must contain valid objects of type '" + req.type + "'.";
172  isValid = false;
173  }
174  // FIXME We can not validate the type of object extracted with 'camp' path.
175  else if (reqKey.path.empty() && obj->getClassname() != req.type)
176  {
177  validation.first = false;
178  validation.second += "\n - The parameter '" + req.name +
179  "' must contain only objects of type '" + req.type + "'.";
180  isValid = false;
181  }
182  }
183 
184  if (isValid)
185  {
186  IValidator::ValidationType val = this->checkObject(currentComposite, req.validator);
187  if (!val.first)
188  {
189  validation.first = false;
190  validation.second += "\n - The parameter '" + req.name + "' is not valid: " + val.second;
191  }
192 
193  }
194  }
195  }
196  }
197  }
198 
199  return validation;
200 }
201 
202 //------------------------------------------------------------------------------
203 
204 IValidator::ValidationType IActivityValidator::checkParameters(const ::fwMedData::ActivitySeries::csptr &activity) const
205 {
206  IValidator::ValidationType validation;
207  validation.first = true;
208  validation.second = "";
209 
211  info = ::fwActivities::registry::Activities::getDefault()->getInfo(activity->getActivityConfigId());
212 
213  ::fwData::Composite::sptr composite = activity->getData();
214 
215  // Check if all the activity config parameters are present
216  ::fwActivities::registry::ActivityAppConfig appConfigInfo = info.appConfig;
217  for (auto param : appConfigInfo.parameters)
218  {
219  if (param.isSeshat())
220  {
221  std::string path = param.by;
222  if (path.substr(0,1) == "!")
223  {
224  path.replace(0, 1, "@");
225  }
226  ::fwData::Object::sptr obj = ::fwDataCamp::getObject(composite, path);
227  if (!obj)
228  {
229  validation.first = false;
230  validation.second += "\n - invalid sesh@ path : '" + path + "'";
231  }
232  }
233  }
234 
235  return validation;
236 }
237 
238 //------------------------------------------------------------------------------
239 
240 IValidator::ValidationType IActivityValidator::checkObject(const ::fwData::Object::csptr &object,
241  const std::string &validatorImpl) const
242 {
244  validation.first = true;
245  validation.second = "";
246 
247  if (validatorImpl.empty())
248  {
249  validation.first = true;
250  validation.second = "Validator implementation is empty, assuming it is valid.";
251  }
252  else
253  {
255  ::fwActivities::IValidator::sptr validator = ::fwActivities::validator::factory::New(validatorImpl);
256  ::fwActivities::IObjectValidator::sptr dataValidator = ::fwActivities::IObjectValidator::dynamicCast(validator);
257 
258  if (!dataValidator)
259  {
260  validation.first = false;
261  validation.second = "Validator '" + validatorImpl + "' cannot be instantiated";
262  }
263  else
264  {
265  validation = dataValidator->validate(object);
266  }
267  }
268 
269  return validation;
270 }
271 
272 //------------------------------------------------------------------------------
273 
274 } // namespace fwActivities
275 
std::pair< bool, std::string > ValidationType
Defines validation result of an activity. First element tells if the activity is validated or not by ...
Definition: IValidator.hpp:39
Holds Activities configuration.
Definition: Activities.hpp:175
FWACTIVITIES_API ValidationType checkRequirements(const std::shared_ptr< const ::fwMedData::ActivitySeries > &activity) const
Checks if all the required data are present in the activity series.
unsigned int maxOccurs
minimum number of data required
Definition: Activities.hpp:97
static FWACTIVITIES_API Activities::sptr getDefault()
Return the default global instance of Activities.
Definition: Activities.cpp:226
FWACTIVITIES_API ValidationType checkObject(const std::shared_ptr< const ::fwData::Object > &object, const std::string &validatorImpl) const
Calls the object validator if it is defined.
std::string validator
parameter description
Definition: Activities.hpp:95
FWACTIVITIES_API ValidationType checkParameters(const std::shared_ptr< const ::fwMedData::ActivitySeries > &activity) const
Checks if all the activity&#39;s AppConfig parameters are valid.
This class defines a vector of objects.
KeyType keys
True if the data must be created if it is not present (only if minOccurs = 0 and maxOccurs = 1) ...
Definition: Activities.hpp:99
unsigned int minOccurs
Implementation of data validator.
Definition: Activities.hpp:96
Base class for each data object.
std::string container
parameter type (ie. fwMedData::ImageSeries)
Definition: Activities.hpp:93
Namespace containing activities data and builder.
This class defines a composite object.
bool create
maximum number of data required
Definition: Activities.hpp:98