SSAGES  0.8.3
Software Suite for Advanced General Ensemble Simulations
ArrayRequirement.h
1 
26 #pragma once
27 
28 #include "Requirement.h"
29 #include "StringRequirement.h"
30 #include "IntegerRequirement.h"
31 #include "NumberRequirement.h"
32 #include "ObjectRequirement.h"
33 #include "RequirementLoader.h"
34 #include <algorithm>
35 #include <set>
36 
37 namespace Json
38 {
40 
44  {
45  private:
47  std::unique_ptr<Requirement> item_;
48 
49  bool addItems_;
50  bool setMin_;
51  bool setMax_;
52  bool unique_;
53 
54  int min_;
55  int max_;
56 
58 
63  template <class T>
64  bool IsUnique(T X)
65  {
66  std::set<T> Y(X.begin(), X.end());
67  return X.size() == Y.size();
68  }
69 
70  public:
73  items_(0), item_(nullptr), addItems_(true),
74  setMin_(false), setMax_(false), unique_(false),
75  min_(0), max_(0) {}
77  {
78  items_.clear();
79  }
80 
82  virtual void ClearErrors() override
83  {
84  if(item_ != nullptr)
85  item_->ClearErrors();
86 
87  for(auto& c : items_)
88  c->ClearErrors();
89 
91  }
92 
94  virtual void ClearNotices() override
95  {
96  if(item_ != nullptr)
97  item_->ClearNotices();
98 
99  for(auto& c : items_)
100  c->ClearNotices();
101 
103  }
104 
106  virtual void Reset() override
107  {
108  items_.clear();
109 
110  item_.reset();
111 
112  addItems_ = true;
113  setMin_ = setMax_ = unique_ = false;
114  min_ = max_ = 0;
115  }
116 
118 
125  virtual void Parse(Value json, const std::string& path) override
126  {
127  Reset();
128  RequirementLoader loader;
129 
130  if(json.isMember("items") && json["items"].isObject())
131  {
132  if((item_ = loader.LoadRequirement(json["items"])))
133  item_->Parse(json["items"], path);
134  }
135  else if(json.isMember("items") && json["items"].isArray())
136  {
137  for(auto& item : json["items"])
138  {
139  if(auto iptr = loader.LoadRequirement(item))
140  {
141  items_.push_back(std::move(iptr));
142  items_.back()->Parse(item, path);
143  }
144  }
145  }
146 
147  if(json.isMember("additionalItems") && json["additionalItems"].isBool())
148  addItems_ = json["additionalItems"].asBool();
149 
150  if(json.isMember("minItems") && json["minItems"].isInt())
151  {
152  setMin_ = true;
153  min_ = json["minItems"].asInt();
154  }
155 
156  if(json.isMember("maxItems") && json["maxItems"].isInt())
157  {
158  setMax_ = true;
159  max_ = json["maxItems"].asInt();
160  }
161 
162  if(json.isMember("uniqueItems") && json["uniqueItems"].isBool())
163  unique_ = json["uniqueItems"].asBool();
164  }
165 
167 
171  virtual void Validate(const Value& json, const std::string& path) override
172  {
173  if(!json.isArray())
174  {
175  PushError(path + ": Must be of type \"array\"");
176  return;
177  }
178 
179  if(item_ != nullptr)
180  {
181  int i = 0;
182  for(const auto& item : json)
183  {
184  item_->Validate(item, path + "/" + std::to_string(i));
185  ++i;
186  }
187 
188  // Merge errors.
189  for(const auto& error : item_->GetErrors())
190  PushError(error);
191 
192  for(const auto& notice : item_->GetNotices())
193  PushNotice(notice);
194  }
195 
196  if(items_.size() != 0)
197  {
198 
199  if(!addItems_ && json.size() > items_.size())
200  PushError(path + ": There cannot be any additional items in the array");
201 
202  int iv = std::min((int)items_.size(), (int)json.size());
203  for(int i = 0; i < iv; ++i)
204  {
205  items_[i]->Validate(json[i], path);
206 
207  // Merge errors.
208  for(const auto& error : items_[i]->GetErrors())
209  PushError(error);
210 
211  for(const auto& notice : items_[i]->GetNotices())
212  PushNotice(notice);
213  }
214  }
215 
216  if(setMin_ && (int)json.size() < min_)
217  PushError(path + ": There must be at least " + std::to_string(min_) + " elements in the array");
218 
219  if(setMax_ && (int)json.size() > max_)
220  PushError(path + ": There must be no more than " + std::to_string(max_) + " elements in the array");
221 
222  if(unique_ && !IsUnique(json))
223  PushError(path + ": Entries must be unique");
224 
225 
226  }
227  };
228 }
bool unique_
True if all Requirements are unique.
virtual void Reset() override
Reset array.
int max_
Maximum value.
Array of Requirements.
bool setMax_
True if maximum has been set.
std::unique_ptr< Requirement > item_
Single Requirement.
void PushError(const std::string &error)
Add error to list of error messages.
Definition: Requirement.h:53
bool setMin_
True if minimum has been set.
bool addItems_
True if items can be added.
std::vector< std::string > GetNotices()
Get list of notices.
Definition: Requirement.h:107
std::vector< std::string > GetErrors()
Get list of error messages.
Definition: Requirement.h:92
virtual void ClearErrors()
Clear list of error messages.
Definition: Requirement.h:95
std::unique_ptr< Requirement > LoadRequirement(const Value &json)
Load specific requirement.
int min_
Minimum value.
ArrayRequirement()
Constructor.
virtual void ClearNotices() override
Clear notices for all Requirements.
virtual void ClearErrors() override
Clear list of error messages for all Requirements.
virtual void Validate(const Value &json, const std::string &path) override
Validate json value.
bool IsUnique(T X)
Test if set is unique.
virtual void Parse(Value json, const std::string &path) override
Parse JSON value and fill array.
Helper class to load Requirement.
virtual void ClearNotices()
Clear list of notice messages.
Definition: Requirement.h:110
Requirements on input files.
Definition: Requirement.h:39
RequireList items_
List of Requirements.
std::vector< std::unique_ptr< Requirement > > RequireList
List of Requirements.
Definition: Requirement.h:117
void PushNotice(const std::string &notice)
Add message to list of notices.
Definition: Requirement.h:62