LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
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?
133  std::ostringstream os;
134  bool first = true;
135  for (std::map<int,std::string>::const_iterator j = _errmsgs.begin();
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  // 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 
159  virtual lsst::pex::exceptions::Exception *clone() const;
160  virtual char const *getType(void) const throw();
161 
165  ValidationError(const ValidationError& that)
166  : lsst::pex::exceptions::LogicError(that), _errors(that._errors)
167  { }
168 
169  ValidationError& operator=(const ValidationError& that) {
170  LogicError::operator=(that);
171  _errors = that._errors;
172  return *this;
173  }
174 
175 // Swig is having trouble with this macro
176 // ValidationError(POL_EARGS_TYPED)
177 // : lsst::pex::exceptions::LogicError(POL_EARGS_UNTYPED,
178 // "policy has unknown validation errors"),
179 // _errors()
180 // { }
181 
185  virtual ~ValidationError() throw();
186 
190  int getParamCount() const { return _errors.size(); }
191 
196  void paramNames(std::list<std::string>& names) const {
197  ParamLookup::const_iterator it;
198  for(it = _errors.begin(); it != _errors.end(); it++)
199  names.push_back(it->first);
200  }
201 
206  std::vector<std::string> getParamNames() const;
207 
211  int getErrors(const std::string& name) const {
212  ParamLookup::const_iterator it = _errors.find(name);
213  if (it != _errors.end())
214  return it->second;
215  else
216  return 0;
217  }
218 
222  void addError(const std::string& name, ErrorType e) {
223  _errors[name] |= e;
224  }
225 
230  int getErrors() const {
231  int out = 0;
232  ParamLookup::const_iterator it;
233  for(it = _errors.begin(); it != _errors.end(); it++)
234  out |= it->second;
235  return out;
236  }
237 
243  std::string describe(std::string prefix = "") const;
244 
248  virtual char const* what(void) const throw();
249 
250 protected:
251  typedef std::map<int, std::string> MsgLookup;
252  typedef std::map<std::string, int> ParamLookup;
253 
254  static MsgLookup _errmsgs;
255 
256  static void _loadMessages();
257 
258  ParamLookup _errors;
259 };
260 
265 class Definition : public lsst::daf::base::Citizen {
266 public:
267 
272  Definition(const std::string& paramName = "")
273  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
274  _name(paramName), _policy(), _wildcard(false)
275  {
276  _policy.reset(new Policy());
277  }
278 
284  Definition(const std::string& paramName, const Policy::Ptr& defn)
285  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
286  _name(paramName), _policy(defn), _wildcard(false)
287  { }
288 
293  Definition(const Policy::Ptr& defn)
294  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
295  _name(), _policy(defn), _wildcard(false)
296  { }
297 
301  Definition(const Definition& that)
302  : lsst::daf::base::Citizen(typeid(*this)), _type(Policy::UNDETERMINED),
303  _name(that._name), _policy(that._policy), _wildcard(false)
304  { }
305 
309  Definition& operator=(const Definition& that) {
310  _type = Policy::UNDETERMINED;
311  _name = that._name;
312  _policy = that._policy;
313  _prefix = that._prefix;
314  _wildcard = that._wildcard;
315  return *this;
316  }
317 
322  Definition& operator=(const Policy::Ptr& defdata) {
323  setData(defdata);
324  return *this;
325  }
326 
327  virtual ~Definition();
328 
332  const std::string& getName() const { return _name; }
333 
335 
339  const std::string getPrefix() const { return _prefix; }
340  void setPrefix(const std::string& prefix) { _prefix = prefix; }
342 
344 
348  const bool isChildDefinition() const { return _wildcard; }
349  void setChildDefinition(bool wildcard) { _wildcard = wildcard; }
350  const bool isWildcard() const { return _wildcard; }
351  void setWildcard(bool wildcard) { _wildcard = wildcard; }
353 
358  void setName(const std::string& newname) { _name = newname; }
359 
363  const Policy::Ptr& getData() const { return _policy; }
364 
368  void setData(const Policy::Ptr& defdata) {
369  _type = Policy::UNDETERMINED;
370  _policy = defdata;
371  }
372 
376  Policy::ValueType getType() const {
377  if (_type == Policy::UNDETERMINED) _type = _determineType();
378  return _type;
379  }
380 
385  std::string getTypeName() const {
386  return Policy::typeName[getType()];
387  }
388 
392  std::string getDefault() const {
393  return _policy->str("default");
394  }
395 
400  const std::string getDescription() const;
401 
406  const int getMaxOccurs() const;
407 
412  const int getMinOccurs() const;
413 
420  void setDefaultIn(Policy& policy, ValidationError* errs=0) const {
421  setDefaultIn(policy, _name, errs);
422  }
423 
429  void setDefaultIn(Policy& policy, const std::string& withName,
430  ValidationError* errs=0) const;
431 
435  template <typename T> void setDefaultIn(Policy& policy,
436  const std::string& withName,
437  ValidationError* errs=0) const;
438 
452  void validate(const Policy& policy, const std::string& name,
453  ValidationError *errs=0) const;
454 
467  void validate(const Policy& policy, ValidationError *errs=0) const {
468  validate(policy, _name, errs);
469  }
470 
472 
495  void validate(const std::string& name, bool value, int curcount=-1,
496  ValidationError *errs=0) const;
497  void validate(const std::string& name, int value, int curcount=-1,
498  ValidationError *errs=0) const;
499  void validate(const std::string& name, double value, int curcount=-1,
500  ValidationError *errs=0) const;
501  void validate(const std::string& name, std::string value, int curcount=-1,
502  ValidationError *errs=0) const;
503  void validate(const std::string& name, const Policy& value, int curcount=-1,
504  ValidationError *errs=0) const;
506 
508 
525  void validate(const std::string& name, const Policy::BoolArray& value,
526  ValidationError *errs=0) const;
527  void validate(const std::string& name, const Policy::IntArray& value,
528  ValidationError *errs=0) const;
529  void validate(const std::string& name, const Policy::DoubleArray& value,
530  ValidationError *errs=0) const;
531  void validate(const std::string& name,
532  const Policy::StringArray& value,
533  ValidationError *errs=0) const;
534  void validate(const std::string& name,
535  const Policy::ConstPolicyPtrArray& value,
536  ValidationError *errs=0) const;
538 
558  template <typename T> void validateBasic
559  (const std::string& name, const Policy& policy,
560  ValidationError *errs=0) const;
561 
563 
572  template <typename T> void validateBasic
573  (const std::string& name, const T& value, int curcount=-1,
574  ValidationError *errs=0) const;
575  template <typename T> void validateBasic
576  (const std::string& name, const std::vector<T>& value,
577  ValidationError *errs=0) const;
579 
581 
588  void validateRecurse(const std::string& name, Policy::ConstPolicyPtrArray value,
589  ValidationError *errs) const;
590 
591  void validateRecurse(const std::string& name, const Policy& value,
592  ValidationError *errs) const;
594 
599  void check() const;
600 
601 protected:
602  Policy::ValueType _determineType() const;
603 
611  void validateCount(const std::string& name, int count,
612  ValidationError *errs) const;
613 
614  static const std::string EMPTY;
615 
616 private:
617  mutable Policy::ValueType _type;
618  std::string _prefix; // for recursive validation, eg "foo.bar."
619  std::string _name;
620  Policy::Ptr _policy;
621  bool _wildcard;
622 };
623 
624 inline std::ostream& operator<<(std::ostream& os, const Definition& d) {
625  d.getData()->print(os, d.getName());
626  return os;
627 }
628 
719 class Dictionary : public Policy {
720 public:
721 
722  // keywords
723  static const char *KW_DICT;
724  static const char *KW_DICT_FILE;
725  static const char *KW_TYPE;
726  static const char *KW_DESCRIPTION;
727  static const char *KW_DEFAULT;
728  static const char *KW_DEFINITIONS;
729  static const char *KW_CHILD_DEF;
730  static const char *KW_ALLOWED;
731  static const char *KW_MIN_OCCUR;
732  static const char *KW_MAX_OCCUR;
733  static const char *KW_MIN;
734  static const char *KW_MAX;
735  static const char *KW_VALUE;
736 
741  Dictionary() : Policy() { }
742 
749  Dictionary(const Policy& pol)
750  : Policy( (pol.isPolicy("dictionary")) ? *(pol.getPolicy("dictionary"))
751  : pol )
752  {
753  check();
754  }
755 
759  Dictionary(const Dictionary& dict) : Policy(dict) {
760  check();
761  }
762 
764 
767  explicit Dictionary(const char *filePath);
768  explicit Dictionary(const std::string& filePath);
769  explicit Dictionary(const PolicyFile& filePath);
771 
773 
776  Policy::ConstPtr getDefinitions() const {
777  return getPolicy("definitions");
778  }
779  Policy::Ptr getDefinitions() {
780  return getPolicy("definitions");
781  }
783 
788  void check() const;
789 
794  int definedNames(std::list<std::string>& names, bool append=false) const {
795  return getDefinitions()->names(names, true, append);
796  }
797 
801  StringArray definedNames() const {
802  return getDefinitions()->names(true);
803  }
804 
809  Definition getDef(const std::string& name) {
810  Definition *def = makeDef(name);
811  Definition out(*def);
812  delete def;
813  return out;
814  }
815 
824  Definition* makeDef(const std::string& name) const;
825 
831  bool hasSubDictionary(const std::string& name) const {
832  std::string key = std::string("definitions.") + name + "." + KW_DICT;
833  // could also check isPolicy(key), but we would rather have
834  // getSubDictionary(name) fail with a DictionaryError if the
835  // sub-dictionary is the wrong type
836  return exists(key);
837  }
838 
840 
845  DictPtr getSubDictionary(const std::string& name) const;
846  // DictPtr getSubDictionary(const std::string& name) const;
848 
865  void validate(const Policy& pol, ValidationError *errs=0) const;
866 
867  // C++ inheritance & function overloading limitations require us to
868  // re-declare this here, even though an identical function is declared in
869  // Policy
883  int loadPolicyFiles(bool strict=true) {
884  return loadPolicyFiles(boost::filesystem::path(), strict);
885  }
886 
895  virtual int loadPolicyFiles(const boost::filesystem::path& repository,
896  bool strict=true);
897 
899 
903  const std::string getPrefix() const { return _prefix; }
904  void setPrefix(const std::string& prefix) { _prefix = prefix; }
906 
907 
908 protected:
909  static const boost::regex FIELDSEP_RE;
910 
911 private:
912  std::string _prefix; // for recursive validation, eg "foo.bar."
913 };
914 
915 template <typename T>
916 void Definition::validateBasic(const std::string& name, const Policy& policy,
917  ValidationError *errs) const
918 {
919  validateBasic(name, policy.getValueArray<T>(name), errs);
920 }
921 
922 template <typename T>
923 void Definition::validateBasic(const std::string& name, const std::vector<T>& value,
924  ValidationError *errs) const
925 {
926  ValidationError ve(LSST_EXCEPT_HERE);
927  ValidationError *use = &ve;
928  if (errs != 0) use = errs;
929 
930  validateCount(name, value.size(), use);
931 
932  for (typename std::vector<T>::const_iterator i = value.begin();
933  i != value.end();
934  ++i)
935  validateBasic<T>(name, *i, -1, use);
936 
937  if (errs == 0 && ve.getParamCount() > 0) throw ve;
938 }
939 
940 template <typename T>
941 void Definition::setDefaultIn(Policy& policy, const std::string& withName,
942  ValidationError *errs) const
943 {
944  ValidationError ve(LSST_EXCEPT_HERE);
945  ValidationError *use = (errs == 0 ? &ve : errs);
946 
947  if (_policy->exists("default")) {
948  const std::vector<T> defs = _policy->getValueArray<T>("default");
949  validateBasic(withName, defs, use);
950  if (use->getErrors(withName) == ValidationError::OK) {
951  policy.remove(withName);
952  for (typename std::vector<T>::const_iterator i = defs.begin();
953  i != defs.end();
954  ++i)
955  policy.addValue<T>(withName, *i);
956  }
957  }
958 
959  if (errs == 0 && ve.getParamCount() > 0) throw ve;
960 }
961 
962 }}} // end namespace lsst::pex::policy
963 
964 #endif // LSST_PEX_POLICY_POLICY_H
std::vector< int > IntArray
Definition: Policy.h:179
table::Key< std::string > name
Definition: ApCorrMap.cc:71
for(FootprintList::const_iterator ptr=feet->begin(), end=feet->end();ptr!=end;++ptr)
Definition: saturated.cc:82
definition of Policy-specific exceptions classes
std::string const & _name
Definition: Mask.cc:678
boost::shared_ptr< const Policy > ConstPtr
Definition: Policy.h:173
boost::shared_ptr< Policy > Ptr
Definition: Policy.h:172
#define LSST_EXCEPT_HERE
Definition: Exception.h:40
static const char *const typeName[]
Definition: Policy.h:205
std::ostream & operator<<(std::ostream &os, const Policy &p)
Definition: Policy.h:890
std::vector< std::string > StringArray
Definition: Policy.h:181
def setPrefix
Set a prefix based on the EUPS_PATH, the product name, and a versionString from cvs or svn...
Definition: installation.py:88
std::vector< double > DoubleArray
Definition: Policy.h:180
def exists
Definition: cuda.py:53
std::vector< bool > BoolArray
Definition: Policy.h:178
std::vector< ConstPtr > ConstPolicyPtrArray
Definition: Policy.h:184