LSSTApplications  20.0.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:
62  enum ErrorType {
64  OK = 0,
65 
67  WRONG_TYPE = 1,
68 
70  MISSING_REQUIRED = 2,
71 
73  NOT_AN_ARRAY = 4,
74 
76  ARRAY_TOO_SHORT = 8,
77 
82  TOO_FEW_VALUES = 14,
83 
85  TOO_MANY_VALUES = 16,
86 
92  WRONG_OCCURRENCE_COUNT = 30,
93 
95  VALUE_DISALLOWED = 32,
96 
101  VALUE_OUT_OF_RANGE = 64,
102 
107  BAD_VALUE = 96,
108 
110  UNKNOWN_NAME = 128,
111 
113  BAD_DEFINITION = 256,
114 
116  NOT_LOADED = 512,
117 
119  UNKNOWN_ERROR = 1024
120  };
121 
122  static const std::string& getErrorMessageFor(ErrorType err) {
123  if (_errmsgs.size() == 0) _loadMessages();
124  MsgLookup::iterator it = _errmsgs.find(err);
125  if (it != _errmsgs.end())
126  return it->second;
127  else {
128  // if it's a compound error that we don't have a pre-written
129  // description of, then compile a description
130  static std::string result; // avoid memory issues
131  // TODO: at cost of concurrence?
133  bool first = true;
134  for (std::map<int, std::string>::const_iterator j = _errmsgs.begin(); j != _errmsgs.end(); ++j) {
135  if (j->first != OK && (err & j->first) == j->first) {
136  os << (first ? "" : "; ") << j->second;
137  first = false;
138  }
139  }
140  result = os.str();
141  return result;
142  }
143  }
144 
145  static const std::string EMPTY;
146 
147  ValidationError(std::string const& message) : lsst::pex::exceptions::LogicError(message), _errors() {}
148 
149  // TODO: create way to change message when an error actually occurs
153  ValidationError(char const* ex_file, int ex_line, char const* ex_func)
154  : lsst::pex::exceptions::LogicError(ex_file, ex_line, ex_func,
155  "Policy has unknown validation errors"),
156  _errors() {}
157 
158  virtual lsst::pex::exceptions::Exception* clone() const;
159  virtual char const* getType(void) const throw();
160 
164  ValidationError(const ValidationError& that)
165  : lsst::pex::exceptions::LogicError(that), _errors(that._errors) {}
166 
167  ValidationError& operator=(const ValidationError& that) {
168  LogicError::operator=(that);
169  _errors = that._errors;
170  return *this;
171  }
172 
173  // Swig is having trouble with this macro
174  // ValidationError(POL_EARGS_TYPED)
175  // : lsst::pex::exceptions::LogicError(POL_EARGS_UNTYPED,
176  // "policy has unknown validation errors"),
177  // _errors()
178  // { }
179 
183  virtual ~ValidationError() throw();
184 
188  int getParamCount() const { return _errors.size(); }
189 
194  void paramNames(std::list<std::string>& names) const {
195  ParamLookup::const_iterator it;
196  for (it = _errors.begin(); it != _errors.end(); it++) names.push_back(it->first);
197  }
198 
203  std::vector<std::string> getParamNames() const;
204 
208  int getErrors(const std::string& name) const {
209  ParamLookup::const_iterator it = _errors.find(name);
210  if (it != _errors.end())
211  return it->second;
212  else
213  return 0;
214  }
215 
219  void addError(const std::string& name, ErrorType e) { _errors[name] |= e; }
220 
225  int getErrors() const {
226  int out = 0;
227  ParamLookup::const_iterator it;
228  for (it = _errors.begin(); it != _errors.end(); it++) out |= it->second;
229  return out;
230  }
231 
237  std::string describe(std::string prefix = "") const;
238 
242  virtual char const* what(void) const throw();
243 
244 protected:
245  typedef std::map<int, std::string> MsgLookup;
246  typedef std::map<std::string, int> ParamLookup;
247 
248  static MsgLookup _errmsgs;
249 
250  static void _loadMessages();
251 
252  ParamLookup _errors;
253 };
254 
259 class Definition {
260 public:
265  Definition(const std::string& paramName = "")
266  : _type(Policy::UNDETERMINED), _name(paramName), _policy(), _wildcard(false) {
267  _policy.reset(new Policy());
268  }
269 
275  Definition(const std::string& paramName, const Policy::Ptr& defn)
276  : _type(Policy::UNDETERMINED), _name(paramName), _policy(defn), _wildcard(false) {}
277 
282  Definition(const Policy::Ptr& defn)
283  : _type(Policy::UNDETERMINED), _name(), _policy(defn), _wildcard(false) {}
284 
288  Definition(const Definition& that)
289  : _type(Policy::UNDETERMINED), _name(that._name), _policy(that._policy), _wildcard(false) {}
290 
294  Definition& operator=(const Definition& that) {
295  _type = Policy::UNDETERMINED;
296  _name = that._name;
297  _policy = that._policy;
298  _prefix = that._prefix;
299  _wildcard = that._wildcard;
300  return *this;
301  }
302 
307  Definition& operator=(const Policy::Ptr& defdata) {
308  setData(defdata);
309  return *this;
310  }
311 
312  virtual ~Definition();
313 
317  const std::string& getName() const { return _name; }
318 
320 
324  const std::string getPrefix() const { return _prefix; }
325  void setPrefix(const std::string& prefix) { _prefix = prefix; }
327 
329 
333  const bool isChildDefinition() const { return _wildcard; }
334  void setChildDefinition(bool wildcard) { _wildcard = wildcard; }
335  const bool isWildcard() const { return _wildcard; }
336  void setWildcard(bool wildcard) { _wildcard = wildcard; }
338 
343  void setName(const std::string& newname) { _name = newname; }
344 
348  const Policy::Ptr& getData() const { return _policy; }
349 
353  void setData(const Policy::Ptr& defdata) {
354  _type = Policy::UNDETERMINED;
355  _policy = defdata;
356  }
357 
361  Policy::ValueType getType() const {
362  if (_type == Policy::UNDETERMINED) _type = _determineType();
363  return _type;
364  }
365 
370  std::string getTypeName() const { return Policy::typeName[getType()]; }
371 
375  std::string getDefault() const { return _policy->str("default"); }
376 
381  const std::string getDescription() const;
382 
387  const int getMaxOccurs() const;
388 
393  const int getMinOccurs() const;
394 
401  void setDefaultIn(Policy& policy, ValidationError* errs = 0) const { setDefaultIn(policy, _name, errs); }
402 
408  void setDefaultIn(Policy& policy, const std::string& withName, ValidationError* errs = 0) const;
409 
413  template <typename T>
414  void setDefaultIn(Policy& policy, const std::string& withName, ValidationError* errs = 0) const;
415 
429  void validate(const Policy& policy, const std::string& name, ValidationError* errs = 0) const;
430 
443  void validate(const Policy& policy, ValidationError* errs = 0) const { validate(policy, _name, errs); }
444 
446 
469  void validate(const std::string& name, bool value, int curcount = -1, ValidationError* errs = 0) const;
470  void validate(const std::string& name, int value, int curcount = -1, ValidationError* errs = 0) const;
471  void validate(const std::string& name, double value, int curcount = -1, ValidationError* errs = 0) const;
472  void validate(const std::string& name, std::string value, int curcount = -1,
473  ValidationError* errs = 0) const;
474  void validate(const std::string& name, const Policy& value, int curcount = -1,
475  ValidationError* errs = 0) const;
477 
479 
496  void validate(const std::string& name, const Policy::BoolArray& value, ValidationError* errs = 0) const;
497  void validate(const std::string& name, const Policy::IntArray& value, ValidationError* errs = 0) const;
498  void validate(const std::string& name, const Policy::DoubleArray& value, ValidationError* errs = 0) const;
499  void validate(const std::string& name, const Policy::StringArray& value, ValidationError* errs = 0) const;
500  void validate(const std::string& name, const Policy::ConstPolicyPtrArray& value,
501  ValidationError* errs = 0) const;
503 
523  template <typename T>
524  void validateBasic(const std::string& name, const Policy& policy, ValidationError* errs = 0) const;
525 
527 
536  template <typename T>
537  void validateBasic(const std::string& name, const T& value, int curcount = -1,
538  ValidationError* errs = 0) const;
539  template <typename T>
540  void validateBasic(const std::string& name, const std::vector<T>& value, ValidationError* errs = 0) const;
542 
544 
551  void validateRecurse(const std::string& name, Policy::ConstPolicyPtrArray value,
552  ValidationError* errs) const;
553 
554  void validateRecurse(const std::string& name, const Policy& value, ValidationError* errs) const;
556 
561  void check() const;
562 
563 protected:
564  Policy::ValueType _determineType() const;
565 
573  void validateCount(const std::string& name, int count, ValidationError* errs) const;
574 
575  static const std::string EMPTY;
576 
577 private:
578  mutable Policy::ValueType _type;
579  std::string _prefix; // for recursive validation, eg "foo.bar."
580  std::string _name;
581  Policy::Ptr _policy;
582  bool _wildcard;
583 };
584 
585 inline std::ostream& operator<<(std::ostream& os, const Definition& d) {
586  d.getData()->print(os, d.getName());
587  return os;
588 }
589 
680 class Dictionary : public Policy {
681 public:
682  // keywords
683  static const char* KW_DICT;
684  static const char* KW_DICT_FILE;
685  static const char* KW_TYPE;
686  static const char* KW_DESCRIPTION;
687  static const char* KW_DEFAULT;
688  static const char* KW_DEFINITIONS;
689  static const char* KW_CHILD_DEF;
690  static const char* KW_ALLOWED;
691  static const char* KW_MIN_OCCUR;
692  static const char* KW_MAX_OCCUR;
693  static const char* KW_MIN;
694  static const char* KW_MAX;
695  static const char* KW_VALUE;
696 
701  Dictionary() : Policy() {}
702 
709  Dictionary(const Policy& pol)
710  : Policy((pol.isPolicy("dictionary")) ? *(pol.getPolicy("dictionary")) : pol) {
711  check();
712  }
713 
717  Dictionary(const Dictionary& dict) : Policy(dict) { check(); }
718 
720 
723  explicit Dictionary(const char* filePath);
724  explicit Dictionary(const std::string& filePath);
725  explicit Dictionary(const PolicyFile& filePath);
727 
729 
732  Policy::ConstPtr getDefinitions() const { return getPolicy("definitions"); }
733  Policy::Ptr getDefinitions() { return getPolicy("definitions"); }
735 
740  void check() const;
741 
746  int definedNames(std::list<std::string>& names, bool append = false) const {
747  return getDefinitions()->names(names, true, append);
748  }
749 
753  StringArray definedNames() const { return getDefinitions()->names(true); }
754 
759  Definition getDef(const std::string& name) {
760  Definition* def = makeDef(name);
761  Definition out(*def);
762  delete def;
763  return out;
764  }
765 
774  Definition* makeDef(const std::string& name) const;
775 
781  bool hasSubDictionary(const std::string& name) const {
782  std::string key = std::string("definitions.") + name + "." + KW_DICT;
783  // could also check isPolicy(key), but we would rather have
784  // getSubDictionary(name) fail with a DictionaryError if the
785  // sub-dictionary is the wrong type
786  return exists(key);
787  }
788 
790 
795  DictPtr getSubDictionary(const std::string& name) const;
796  // DictPtr getSubDictionary(const std::string& name) const;
798 
815  void validate(const Policy& pol, ValidationError* errs = 0) const;
816 
817  // C++ inheritance & function overloading limitations require us to
818  // re-declare this here, even though an identical function is declared in
819  // Policy
833  int loadPolicyFiles(bool strict = true) { return loadPolicyFiles(boost::filesystem::path(), strict); }
834 
843  virtual int loadPolicyFiles(const boost::filesystem::path& repository, bool strict = true);
844 
846 
850  const std::string getPrefix() const { return _prefix; }
851  void setPrefix(const std::string& prefix) { _prefix = prefix; }
853 
854 protected:
855  static const boost::regex FIELDSEP_RE;
856 
857 private:
858  std::string _prefix; // for recursive validation, eg "foo.bar."
859 };
860 
861 template <typename T>
862 void Definition::validateBasic(const std::string& name, const Policy& policy, ValidationError* errs) const {
863  validateBasic(name, policy.getValueArray<T>(name), errs);
864 }
865 
866 template <typename T>
867 void Definition::validateBasic(const std::string& name, const std::vector<T>& value,
868  ValidationError* errs) const {
869  ValidationError ve(LSST_EXCEPT_HERE);
870  ValidationError* use = &ve;
871  if (errs != 0) use = errs;
872 
873  validateCount(name, value.size(), use);
874 
875  for (typename std::vector<T>::const_iterator i = value.begin(); i != value.end(); ++i)
876  validateBasic<T>(name, *i, -1, use);
877 
878  if (errs == 0 && ve.getParamCount() > 0) throw ve;
879 }
880 
881 template <typename T>
882 void Definition::setDefaultIn(Policy& policy, const std::string& withName, ValidationError* errs) const {
883  ValidationError ve(LSST_EXCEPT_HERE);
884  ValidationError* use = (errs == 0 ? &ve : errs);
885 
886  if (_policy->exists("default")) {
887  const std::vector<T> defs = _policy->getValueArray<T>("default");
888  validateBasic(withName, defs, use);
889  if (use->getErrors(withName) == ValidationError::OK) {
890  policy.remove(withName);
891  for (typename std::vector<T>::const_iterator i = defs.begin(); i != defs.end(); ++i)
892  policy.addValue<T>(withName, *i);
893  }
894  }
895 
896  if (errs == 0 && ve.getParamCount() > 0) throw ve;
897 }
898 
899 } // namespace policy
900 } // namespace pex
901 } // namespace lsst
902 
903 #endif // LSST_PEX_POLICY_POLICY_H
lsst::pex::policy::Policy::DoubleArray
std::vector< double > DoubleArray
Definition: Policy.h:177
std::string
STL class.
std::list< std::string >
lsst::pex::policy::Policy::ValueType
ValueType
an enumeration for the supported policy types
Definition: Policy.h:186
lsst::pex::policy::Policy::ConstPtr
std::shared_ptr< const Policy > ConstPtr
Definition: Policy.h:170
lsst::pex::policy::Policy::typeName
static const char *const typeName[]
c-string forms for the supported value types.
Definition: Policy.h:193
std::vector< std::string >
std::vector::size
T size(T... args)
lsst::pex::policy::Policy::StringArray
std::vector< std::string > StringArray
Definition: Policy.h:178
lsst::afw::table._match.first
first
Definition: _match.py:76
ast::append
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33
lsst::afw::geom.transform.transformContinued.name
string name
Definition: transformContinued.py:32
pex
Definition: __init__.py:1
lsst::pex::policy::Policy::BoolArray
std::vector< bool > BoolArray
Definition: Policy.h:175
std::list::push_back
T push_back(T... args)
lsst::pex::policy::Policy::ConstPolicyPtrArray
std::vector< ConstPtr > ConstPolicyPtrArray
Definition: Policy.h:181
lsst::pex::policy::Policy::UNDETERMINED
@ UNDETERMINED
Definition: Policy.h:186
Policy.h
lsst::pex::policy::Policy::Ptr
std::shared_ptr< Policy > Ptr
Definition: Policy.h:169
std::ostream
STL class.
lsst::pex::policy::Policy::IntArray
std::vector< int > IntArray
Definition: Policy.h:176
lsst::pex::exceptions::LogicError
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
lsst::pex::policy::operator<<
std::ostream & operator<<(std::ostream &os, const Policy &p)
Definition: Policy.h:848
std::map
STL class.
result
py::object result
Definition: _schema.cc:429
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
std::ostringstream
STL class.
os
std::ostream * os
Definition: Schema.cc:746
exceptions.h
definition of Policy-specific exceptions classes
std::map::begin
T begin(T... args)
key
Key< U > key
Definition: Schema.cc:281
LSST_EXCEPT_HERE
#define LSST_EXCEPT_HERE
For internal use; gathers the file, line, and function for a tracepoint.
Definition: Exception.h:40
lsst::pex::exceptions::Exception
Provides consistent interface for LSST exceptions.
Definition: Exception.h:107
std::vector::end
T end(T... args)
lsst::afw::image.slicing.clone
clone
Definition: slicing.py:257
prefix
std::string prefix
Definition: SchemaMapper.cc:79
pex.config.wrap.validate
validate
Definition: wrap.py:295