LSSTApplications  18.1.0
LSSTDataManagementBasePackage
Dictionary.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
32 #ifndef LSST_PEX_POLICY_DICTIONARY_H
33 #define LSST_PEX_POLICY_DICTIONARY_H
34 
35 #include "lsst/pex/policy/Policy.h"
37 #include <boost/regex.hpp>
38 #include <sstream>
39 
40 namespace lsst {
41 namespace pex {
42 namespace policy {
43 
44 class PolicySource;
45 class PolicyFile;
46 
55 class ValidationError : public lsst::pex::exceptions::LogicError {
56 public:
57 
63  enum ErrorType {
65  OK = 0,
66 
68  WRONG_TYPE = 1,
69 
71  MISSING_REQUIRED = 2,
72 
74  NOT_AN_ARRAY = 4,
75 
77  ARRAY_TOO_SHORT = 8,
78 
83  TOO_FEW_VALUES = 14,
84 
86  TOO_MANY_VALUES = 16,
87 
93  WRONG_OCCURRENCE_COUNT = 30,
94 
96  VALUE_DISALLOWED = 32,
97 
102  VALUE_OUT_OF_RANGE = 64,
103 
108  BAD_VALUE = 96,
109 
111  UNKNOWN_NAME = 128,
112 
114  BAD_DEFINITION = 256,
115 
117  NOT_LOADED = 512,
118 
120  UNKNOWN_ERROR = 1024
121  };
122 
123  static const std::string& getErrorMessageFor(ErrorType err) {
124  if (_errmsgs.size() == 0) _loadMessages();
125  MsgLookup::iterator it = _errmsgs.find(err);
126  if (it != _errmsgs.end())
127  return it->second;
128  else {
129  // if it's a compound error that we don't have a pre-written
130  // description of, then compile a description
131  static std::string result; // avoid memory issues
132  // TODO: at cost of concurrence?
134  bool first = true;
136  j != _errmsgs.end(); ++j) {
137  if (j->first != OK && (err & j->first) == j->first) {
138  os << (first ? "" : "; ") << j->second;
139  first = false;
140  }
141  }
142  result = os.str();
143  return result;
144  }
145  }
146 
147  static const std::string EMPTY;
148 
149  ValidationError(std::string const & message) : lsst::pex::exceptions::LogicError(message), _errors()
150  { }
151 
152  // TODO: create way to change message when an error actually occurs
156  ValidationError(char const* ex_file, int ex_line, char const* ex_func)
157  : lsst::pex::exceptions::LogicError(ex_file, ex_line, ex_func,
158  "Policy has unknown validation errors"),
159  _errors()
160  { }
161 
162  virtual lsst::pex::exceptions::Exception *clone() const;
163  virtual char const *getType(void) const throw();
164 
168  ValidationError(const ValidationError& that)
169  : lsst::pex::exceptions::LogicError(that), _errors(that._errors)
170  { }
171 
172  ValidationError& operator=(const ValidationError& that) {
173  LogicError::operator=(that);
174  _errors = that._errors;
175  return *this;
176  }
177 
178 // Swig is having trouble with this macro
179 // ValidationError(POL_EARGS_TYPED)
180 // : lsst::pex::exceptions::LogicError(POL_EARGS_UNTYPED,
181 // "policy has unknown validation errors"),
182 // _errors()
183 // { }
184 
188  virtual ~ValidationError() throw();
189 
193  int getParamCount() const { return _errors.size(); }
194 
199  void paramNames(std::list<std::string>& names) const {
200  ParamLookup::const_iterator it;
201  for(it = _errors.begin(); it != _errors.end(); it++)
202  names.push_back(it->first);
203  }
204 
209  std::vector<std::string> getParamNames() const;
210 
214  int getErrors(const std::string& name) const {
215  ParamLookup::const_iterator it = _errors.find(name);
216  if (it != _errors.end())
217  return it->second;
218  else
219  return 0;
220  }
221 
225  void addError(const std::string& name, ErrorType e) {
226  _errors[name] |= e;
227  }
228 
233  int getErrors() const {
234  int out = 0;
235  ParamLookup::const_iterator it;
236  for(it = _errors.begin(); it != _errors.end(); it++)
237  out |= it->second;
238  return out;
239  }
240 
246  std::string describe(std::string prefix = "") const;
247 
251  virtual char const* what(void) const throw();
252 
253 protected:
254  typedef std::map<int, std::string> MsgLookup;
255  typedef std::map<std::string, int> ParamLookup;
256 
257  static MsgLookup _errmsgs;
258 
259  static void _loadMessages();
260 
261  ParamLookup _errors;
262 };
263 
268 class Definition : public lsst::daf::base::Citizen {
269 public:
270 
275  Definition(const std::string& paramName = "")
276  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
277  _name(paramName), _policy(), _wildcard(false)
278  {
279  _policy.reset(new Policy());
280  }
281 
287  Definition(const std::string& paramName, const Policy::Ptr& defn)
288  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
289  _name(paramName), _policy(defn), _wildcard(false)
290  { }
291 
296  Definition(const Policy::Ptr& defn)
297  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
298  _name(), _policy(defn), _wildcard(false)
299  { }
300 
304  Definition(const Definition& that)
305  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
306  _name(that._name), _policy(that._policy), _wildcard(false)
307  { }
308 
312  Definition& operator=(const Definition& that) {
313  _type = Policy::UNDETERMINED;
314  _name = that._name;
315  _policy = that._policy;
316  _prefix = that._prefix;
317  _wildcard = that._wildcard;
318  return *this;
319  }
320 
325  Definition& operator=(const Policy::Ptr& defdata) {
326  setData(defdata);
327  return *this;
328  }
329 
330  virtual ~Definition();
331 
335  const std::string& getName() const { return _name; }
336 
338 
342  const std::string getPrefix() const { return _prefix; }
343  void setPrefix(const std::string& prefix) { _prefix = prefix; }
345 
347 
351  const bool isChildDefinition() const { return _wildcard; }
352  void setChildDefinition(bool wildcard) { _wildcard = wildcard; }
353  const bool isWildcard() const { return _wildcard; }
354  void setWildcard(bool wildcard) { _wildcard = wildcard; }
356 
361  void setName(const std::string& newname) { _name = newname; }
362 
366  const Policy::Ptr& getData() const { return _policy; }
367 
371  void setData(const Policy::Ptr& defdata) {
372  _type = Policy::UNDETERMINED;
373  _policy = defdata;
374  }
375 
379  Policy::ValueType getType() const {
380  if (_type == Policy::UNDETERMINED) _type = _determineType();
381  return _type;
382  }
383 
388  std::string getTypeName() const {
389  return Policy::typeName[getType()];
390  }
391 
395  std::string getDefault() const {
396  return _policy->str("default");
397  }
398 
403  const std::string getDescription() const;
404 
409  const int getMaxOccurs() const;
410 
415  const int getMinOccurs() const;
416 
423  void setDefaultIn(Policy& policy, ValidationError* errs=0) const {
424  setDefaultIn(policy, _name, errs);
425  }
426 
432  void setDefaultIn(Policy& policy, const std::string& withName,
433  ValidationError* errs=0) const;
434 
438  template <typename T> void setDefaultIn(Policy& policy,
439  const std::string& withName,
440  ValidationError* errs=0) const;
441 
455  void validate(const Policy& policy, const std::string& name,
456  ValidationError *errs=0) const;
457 
470  void validate(const Policy& policy, ValidationError *errs=0) const {
471  validate(policy, _name, errs);
472  }
473 
475 
498  void validate(const std::string& name, bool value, int curcount=-1,
499  ValidationError *errs=0) const;
500  void validate(const std::string& name, int value, int curcount=-1,
501  ValidationError *errs=0) const;
502  void validate(const std::string& name, double value, int curcount=-1,
503  ValidationError *errs=0) const;
504  void validate(const std::string& name, std::string value, int curcount=-1,
505  ValidationError *errs=0) const;
506  void validate(const std::string& name, const Policy& value, int curcount=-1,
507  ValidationError *errs=0) const;
509 
511 
528  void validate(const std::string& name, const Policy::BoolArray& value,
529  ValidationError *errs=0) const;
530  void validate(const std::string& name, const Policy::IntArray& value,
531  ValidationError *errs=0) const;
532  void validate(const std::string& name, const Policy::DoubleArray& value,
533  ValidationError *errs=0) const;
534  void validate(const std::string& name,
535  const Policy::StringArray& value,
536  ValidationError *errs=0) const;
537  void validate(const std::string& name,
538  const Policy::ConstPolicyPtrArray& value,
539  ValidationError *errs=0) const;
541 
561  template <typename T> void validateBasic
562  (const std::string& name, const Policy& policy,
563  ValidationError *errs=0) const;
564 
566 
575  template <typename T> void validateBasic
576  (const std::string& name, const T& value, int curcount=-1,
577  ValidationError *errs=0) const;
578  template <typename T> void validateBasic
579  (const std::string& name, const std::vector<T>& value,
580  ValidationError *errs=0) const;
582 
584 
591  void validateRecurse(const std::string& name, Policy::ConstPolicyPtrArray value,
592  ValidationError *errs) const;
593 
594  void validateRecurse(const std::string& name, const Policy& value,
595  ValidationError *errs) const;
597 
602  void check() const;
603 
604 protected:
605  Policy::ValueType _determineType() const;
606 
614  void validateCount(const std::string& name, int count,
615  ValidationError *errs) const;
616 
617  static const std::string EMPTY;
618 
619 private:
620  mutable Policy::ValueType _type;
621  std::string _prefix; // for recursive validation, eg "foo.bar."
622  std::string _name;
623  Policy::Ptr _policy;
624  bool _wildcard;
625 };
626 
627 inline std::ostream& operator<<(std::ostream& os, const Definition& d) {
628  d.getData()->print(os, d.getName());
629  return os;
630 }
631 
722 class Dictionary : public Policy {
723 public:
724 
725  // keywords
726  static const char *KW_DICT;
727  static const char *KW_DICT_FILE;
728  static const char *KW_TYPE;
729  static const char *KW_DESCRIPTION;
730  static const char *KW_DEFAULT;
731  static const char *KW_DEFINITIONS;
732  static const char *KW_CHILD_DEF;
733  static const char *KW_ALLOWED;
734  static const char *KW_MIN_OCCUR;
735  static const char *KW_MAX_OCCUR;
736  static const char *KW_MIN;
737  static const char *KW_MAX;
738  static const char *KW_VALUE;
739 
744  Dictionary() : Policy() { }
745 
752  Dictionary(const Policy& pol)
753  : Policy( (pol.isPolicy("dictionary")) ? *(pol.getPolicy("dictionary"))
754  : pol )
755  {
756  check();
757  }
758 
762  Dictionary(const Dictionary& dict) : Policy(dict) {
763  check();
764  }
765 
767 
770  explicit Dictionary(const char *filePath);
771  explicit Dictionary(const std::string& filePath);
772  explicit Dictionary(const PolicyFile& filePath);
774 
776 
779  Policy::ConstPtr getDefinitions() const {
780  return getPolicy("definitions");
781  }
782  Policy::Ptr getDefinitions() {
783  return getPolicy("definitions");
784  }
786 
791  void check() const;
792 
797  int definedNames(std::list<std::string>& names, bool append=false) const {
798  return getDefinitions()->names(names, true, append);
799  }
800 
804  StringArray definedNames() const {
805  return getDefinitions()->names(true);
806  }
807 
812  Definition getDef(const std::string& name) {
813  Definition *def = makeDef(name);
814  Definition out(*def);
815  delete def;
816  return out;
817  }
818 
827  Definition* makeDef(const std::string& name) const;
828 
834  bool hasSubDictionary(const std::string& name) const {
835  std::string key = std::string("definitions.") + name + "." + KW_DICT;
836  // could also check isPolicy(key), but we would rather have
837  // getSubDictionary(name) fail with a DictionaryError if the
838  // sub-dictionary is the wrong type
839  return exists(key);
840  }
841 
843 
848  DictPtr getSubDictionary(const std::string& name) const;
849  // DictPtr getSubDictionary(const std::string& name) const;
851 
868  void validate(const Policy& pol, ValidationError *errs=0) const;
869 
870  // C++ inheritance & function overloading limitations require us to
871  // re-declare this here, even though an identical function is declared in
872  // Policy
886  int loadPolicyFiles(bool strict=true) {
887  return loadPolicyFiles(boost::filesystem::path(), strict);
888  }
889 
898  virtual int loadPolicyFiles(const boost::filesystem::path& repository,
899  bool strict=true);
900 
902 
906  const std::string getPrefix() const { return _prefix; }
907  void setPrefix(const std::string& prefix) { _prefix = prefix; }
909 
910 
911 protected:
912  static const boost::regex FIELDSEP_RE;
913 
914 private:
915  std::string _prefix; // for recursive validation, eg "foo.bar."
916 };
917 
918 template <typename T>
919 void Definition::validateBasic(const std::string& name, const Policy& policy,
920  ValidationError *errs) const
921 {
922  validateBasic(name, policy.getValueArray<T>(name), errs);
923 }
924 
925 template <typename T>
926 void Definition::validateBasic(const std::string& name, const std::vector<T>& value,
927  ValidationError *errs) const
928 {
929  ValidationError ve(LSST_EXCEPT_HERE);
930  ValidationError *use = &ve;
931  if (errs != 0) use = errs;
932 
933  validateCount(name, value.size(), use);
934 
935  for (typename std::vector<T>::const_iterator i = value.begin();
936  i != value.end();
937  ++i)
938  validateBasic<T>(name, *i, -1, use);
939 
940  if (errs == 0 && ve.getParamCount() > 0) throw ve;
941 }
942 
943 template <typename T>
944 void Definition::setDefaultIn(Policy& policy, const std::string& withName,
945  ValidationError *errs) const
946 {
947  ValidationError ve(LSST_EXCEPT_HERE);
948  ValidationError *use = (errs == 0 ? &ve : errs);
949 
950  if (_policy->exists("default")) {
951  const std::vector<T> defs = _policy->getValueArray<T>("default");
952  validateBasic(withName, defs, use);
953  if (use->getErrors(withName) == ValidationError::OK) {
954  policy.remove(withName);
955  for (typename std::vector<T>::const_iterator i = defs.begin();
956  i != defs.end();
957  ++i)
958  policy.addValue<T>(withName, *i);
959  }
960  }
961 
962  if (errs == 0 && ve.getParamCount() > 0) throw ve;
963 }
964 
965 }}} // end namespace lsst::pex::policy
966 
967 #endif // LSST_PEX_POLICY_POLICY_H
std::vector< bool > BoolArray
Definition: Policy.h:178
std::vector< std::string > StringArray
Definition: Policy.h:181
std::vector< double > DoubleArray
Definition: Policy.h:180
py::object result
Definition: schema.cc:418
T end(T... args)
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
std::string prefix
Definition: SchemaMapper.cc:79
#define LSST_EXCEPT_HERE
For internal use; gathers the file, line, and function for a tracepoint.
Definition: Exception.h:40
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33
STL class.
std::ostream & operator<<(std::ostream &os, const Policy &p)
Definition: Policy.h:890
STL class.
std::vector< ConstPtr > ConstPolicyPtrArray
Definition: Policy.h:184
T push_back(T... args)
std::shared_ptr< const Policy > ConstPtr
Definition: Policy.h:173
A base class for image defects.
definition of Policy-specific exceptions classes
std::shared_ptr< Policy > Ptr
Definition: Policy.h:172
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
T find(T... args)
T size(T... args)
T begin(T... args)
Key< U > key
Definition: Schema.cc:281
static const char *const typeName[]
c-string forms for the supported value types.
Definition: Policy.h:205
std::vector< int > IntArray
Definition: Policy.h:179
Citizen is a class that should be among all LSST classes base classes, and handles basic memory manag...
Definition: Citizen.h:55
STL class.
std::ostream * os
Definition: Schema.cc:746
ValueType
an enumeration for the supported policy types
Definition: Policy.h:189