LSSTApplications  18.0.0+106,18.0.0+50,19.0.0,19.0.0+1,19.0.0+10,19.0.0+11,19.0.0+13,19.0.0+17,19.0.0+2,19.0.0-1-g20d9b18+6,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+6,19.0.0-1-g6fe20d0+1,19.0.0-1-g7011481+9,19.0.0-1-g8c57eb9+6,19.0.0-1-gb5175dc+11,19.0.0-1-gdc0e4a7+9,19.0.0-1-ge272bc4+6,19.0.0-1-ge3aa853,19.0.0-10-g448f008b,19.0.0-12-g6990b2c,19.0.0-2-g0d9f9cd+11,19.0.0-2-g3d9e4fb2+11,19.0.0-2-g5037de4,19.0.0-2-gb96a1c4+3,19.0.0-2-gd955cfd+15,19.0.0-3-g2d13df8,19.0.0-3-g6f3c7dc,19.0.0-4-g725f80e+11,19.0.0-4-ga671dab3b+1,19.0.0-4-gad373c5+3,19.0.0-5-ga2acb9c+2,19.0.0-5-gfe96e6c+2,w.2020.01
LSSTDataManagementBasePackage
Policy.cc
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2008, 2009, 2010 LSST Corporation.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <http://www.lsstcorp.org/LegalNotices/>.
21  */
22 
26 #include "lsst/pex/policy/Policy.h"
32 // #include "lsst/pex/logging/Trace.h"
33 
34 #include <memory>
35 #include <boost/filesystem/path.hpp>
36 
37 #include <stdexcept>
38 #include <string>
39 #include <cctype>
40 #include <algorithm>
41 #include <sstream>
42 
43 using namespace std;
44 namespace fs = boost::filesystem;
46 namespace dafBase = lsst::daf::base;
47 
48 namespace lsst {
49 namespace pex {
50 namespace policy {
51 
52 //@cond
53 
56 
57 const char* const Policy::typeName[] = {"undefined", "bool", "int", "double",
58  "string", "Policy", "PolicyFile"};
59 
60 /*
61  * Create an empty policy
62  */
63 Policy::Policy() : Persistable(), _data(new PropertySet()) {}
64 
65 /*
66  * Create policy
67  */
68 Policy::Policy(const PolicySource& source) : Persistable(), _data(new PropertySet()) { source.load(*this); }
69 
70 /*
71  * Create a Policy from a named file or URN.
72  */
73 Policy::Policy(const string& pathOrUrn) : Persistable(), _data(new PropertySet()) {
74  createPolicyFile(pathOrUrn, true)->load(*this);
75 }
76 
77 /*
78  * Create a Policy from a named file or URN.
79  */
80 Policy::Policy(const char* pathOrUrn) : Persistable(), _data(new PropertySet()) {
81  createPolicyFile(pathOrUrn, true)->load(*this);
82 }
83 
91 Policy::FilePtr Policy::createPolicyFile(const string& pathOrUrn, bool strict) {
92  if (UrnPolicyFile::looksLikeUrn(pathOrUrn, strict))
93  // return std::make_shared<PolicyFile>(new UrnPolicyFile(pathOrUrn));
94  return Policy::FilePtr(new UrnPolicyFile(pathOrUrn));
95  else
96  // return std::make_shared<PolicyFile>(new PolicyFile(pathOrUrn));
97  return Policy::FilePtr(new PolicyFile(pathOrUrn));
98 }
99 
100 /* Extract defaults from dict into target. Note any errors in ve. */
101 void extractDefaults(Policy& target, const Dictionary& dict, ValidationError& ve) {
103  dict.definedNames(names);
104 
105  for (list<string>::iterator it = names.begin(); it != names.end(); ++it) {
106  const string& name = *it;
107  std::auto_ptr<Definition> def(dict.makeDef(name));
108  def->setDefaultIn(target, &ve);
109  // recurse into sub-dictionaries
110  if (def->getType() == Policy::POLICY && dict.hasSubDictionary(name)) {
111  Policy::Ptr subp = std::make_shared<Policy>();
112  extractDefaults(*subp, *dict.getSubDictionary(name), ve);
113  if (subp->nameCount() > 0) target.add(name, subp);
114  }
115  }
116 }
117 
131 Policy::Policy(bool validate, const Dictionary& dict, const fs::path& repository)
132  : Persistable(), _data(new PropertySet()) {
133  DictPtr loadedDict; // the dictionary that has all policy files loaded
134  if (validate) { // keep loadedDict around for future validation
135  setDictionary(dict);
136  loadedDict = _dictionary;
137  } else { // discard loadedDict when we finish constructor
138  loadedDict.reset(new Dictionary(dict));
139  }
140  loadedDict->loadPolicyFiles(repository, true);
141 
142  ValidationError ve(LSST_EXCEPT_HERE);
143  extractDefaults(*this, *loadedDict, ve);
144  if (ve.getParamCount() > 0) throw ve;
145 }
146 
147 /*
148  * copy a Policy. Sub-policy objects will not be shared.
149  */
150 Policy::Policy(const Policy& pol) : Persistable(), _data() { _data = pol._data->deepCopy(); }
151 
152 /*
153  * copy a Policy. Sub-policy objects will be shared unless deep is true
154  */
155 Policy::Policy(Policy& pol, bool deep) : Persistable(), _data() {
156  if (deep)
157  _data = pol._data->deepCopy();
158  else
159  _data = pol._data;
160 }
161 
162 Policy* Policy::_createPolicy(PolicySource& source, bool doIncludes, const fs::path& repository,
163  bool validate) {
164  auto_ptr<Policy> pol(new Policy());
165  source.load(*pol);
166 
167  if (pol->isDictionary()) {
168  Dictionary d(*pol);
169  pol.reset(new Policy(validate, d, repository));
170  }
171 
172  if (doIncludes) pol->loadPolicyFiles(repository, true);
173 
174  return pol.release();
175 }
176 
177 Policy* Policy::_createPolicy(const string& input, bool doIncludes, const fs::path& repository,
178  bool validate) {
179  fs::path repos = repository;
180  if (repos.empty()) {
181  fs::path filepath(input);
182  if (filepath.has_parent_path()) repos = filepath.parent_path();
183  }
184  PolicyFile file(input);
185  return _createPolicy(file, doIncludes, repos, validate);
186 }
187 
188 Policy* Policy::createPolicyFromUrn(const std::string& urn, bool validate) {
189  // Note: Don't request doIncludes because UrnPolicyFile will load the whole
190  // thing anyway.
191  UrnPolicyFile upf(urn, true, true);
192  return _createPolicy(upf, true, fs::path(), false);
193 }
194 
195 /*
196  * Create an empty policy
197  */
198 Policy::~Policy() {}
199 
205 bool Policy::canValidate() const { return static_cast<bool>(_dictionary); }
206 
211 const Policy::ConstDictPtr Policy::getDictionary() const { return _dictionary; }
212 
218 void Policy::setDictionary(const Dictionary& dict) { _dictionary = std::make_shared<Dictionary>(dict); }
219 
230 void Policy::validate(ValidationError* errs) const {
231  if (!_dictionary)
232  throw LSST_EXCEPT(DictionaryError, "No dictionary set.");
233  else
234  _dictionary->validate(*this, errs);
235 }
236 
242 Policy::ValueType Policy::getTypeByName(const string& name) {
243  static map<string, Policy::ValueType> nameTypeMap;
244 
245  if (nameTypeMap.size() == 0) {
247  int n = sizeof(Policy::typeName) / sizeof(char*);
248  for (int i = 0; i < n; ++i) {
249  // remember both capitalized and lowercase versions (eg Policy)
250  tmp[Policy::typeName[i]] = (Policy::ValueType)i;
251  string lowered(Policy::typeName[i]);
252  transform(lowered.begin(), lowered.end(), lowered.begin(), ::tolower);
253  tmp[lowered] = (Policy::ValueType)i;
254  }
255  // a few extras
256  tmp["file"] = Policy::FILE;
257  tmp["boolean"] = Policy::BOOL;
258  tmp["integer"] = Policy::INT;
259  tmp["undef"] = Policy::UNDEF;
260  // assign after initializationto avoid concurrency problems
261  nameTypeMap = tmp;
262 
263  if (tmp.count(name) == 1) return tmp[name];
264  } else if (nameTypeMap.count(name) == 1)
265  return nameTypeMap[name];
266 
267  throw LSST_EXCEPT(BadNameError, name);
268 }
269 
270 /*
271  * load the names of parameters into a given list.
272  *
273  * @param prepend the names string to prepend to any names found.
274  * @param names the list object to be loaded
275  * @param topLevelOnly if true, only parameter names at the top of the
276  * hierarchy will be returned; no hierarchical
277  * names will be included.
278  * @param append if false, the contents of the given list will
279  * be erased before loading the names.
280  * @param want a bit field indicating which is desired (1=Policies,
281  * 2=PolicyFiles, 4=parameters, 7=all).
282  * @return int the number of names added
283  */
284 int Policy::_names(vector<string>& names, bool topLevelOnly, bool append, int want) const {
285  bool shouldCheck = true;
287  int have = 0, count = 0;
288  if (want == 1) {
289  src = _data->propertySetNames(topLevelOnly);
290  have = 1;
291  shouldCheck = false;
292  } else if (want == 7)
293  src = _data->names(topLevelOnly);
294  else
295  src = _data->paramNames(topLevelOnly);
296 
297  if (!append) names.erase(names.begin(), names.end());
298 
299  StringArray::iterator i;
300  for (i = src.begin(); i != src.end(); ++i) {
301  if (shouldCheck) {
302  if (isPolicy(*i))
303  have = 1;
304  else if (isFile(*i))
305  have = 2;
306  else
307  have = 4;
308  }
309  if ((have & want) > 0) {
310  names.push_back(*i);
311  count++;
312  }
313  }
314 
315  return count;
316 }
317 
318 /*
319  * load the names of parameters into a given list.
320  *
321  * @param prepend the names string to prepend to any names found.
322  * @param names the list object to be loaded
323  * @param topLevelOnly if true, only parameter names at the top of the
324  * hierarchy will be returned; no hierarchical
325  * names will be included.
326  * @param append if false, the contents of the given list will
327  * be erased before loading the names.
328  * @param want a bit field indicating which is desired (1=Policies,
329  * 2=PolicyFiles, 4=parameters, 7=all).
330  * @return int the number of names added
331  */
332 int Policy::_names(list<string>& names, bool topLevelOnly, bool append, int want) const {
333  bool shouldCheck = true;
335  int have = 0, count = 0;
336  if (want == 1) {
337  src = _data->propertySetNames(topLevelOnly);
338  have = 1;
339  shouldCheck = false;
340  } else if (want == 7)
341  src = _data->names(topLevelOnly);
342  else
343  src = _data->paramNames(topLevelOnly);
344 
345  if (!append) names.erase(names.begin(), names.end());
346 
347  StringArray::iterator i;
348  for (i = src.begin(); i != src.end(); ++i) {
349  if (shouldCheck) {
350  if (isPolicy(*i))
351  have = 1;
352  else if (isFile(*i))
353  have = 2;
354  else
355  have = 4;
356  }
357  if ((have & want) > 0) {
358  names.push_back(*i);
359  count++;
360  }
361  }
362 
363  return count;
364 }
365 
366 template <class T>
367 void Policy::_validate(const std::string& name, const T& value, int curCount) {
368  if (_dictionary) {
369  try {
370  std::unique_ptr<Definition> def(_dictionary->makeDef(name));
371  def->validateBasic(name, value, curCount);
372  } catch (NameNotFound& e) {
373  ValidationError ve(LSST_EXCEPT_HERE);
374  ve.addError(name, ValidationError::UNKNOWN_NAME);
375  throw ve;
376  }
377  }
378 }
379 
380 template void Policy::_validate<Policy::Ptr>(std::string const&, Policy::Ptr const&, int);
381 template void Policy::_validate<std::string>(std::string const&, std::string const&, int);
382 template void Policy::_validate<bool>(std::string const&, bool const&, int);
383 template void Policy::_validate<double>(std::string const&, double const&, int);
384 template void Policy::_validate<int>(std::string const&, int const&, int);
385 
386 /*
387  * return the type information for the underlying type associated with
388  * a given name.
389  */
390 Policy::ValueType Policy::getValueType(const string& name) const {
391  try {
392  const std::type_info& tp = _data->typeOf(name);
393 
394  // handle the special case of FilePtr first
396  try {
397  getFile(name);
398  return FILE;
399  } catch (...) {
400  }
401  }
402 
403  if (tp == typeid(bool)) {
404  return BOOL;
405  } else if (tp == typeid(int)) {
406  return INT;
407  } else if (tp == typeid(double)) {
408  return DOUBLE;
409  } else if (tp == typeid(string)) {
410  return STRING;
412  return POLICY;
413  } else {
415  string("Policy: illegal type held by PropertySet: ") + tp.name());
416  }
417  } catch (pexExcept::NotFoundError&) {
418  return UNDEF;
419  }
420 }
421 
422 template <>
423 bool Policy::getValue<bool>(const string& name) const {
424  return getBool(name);
425 }
426 template <>
427 int Policy::getValue<int>(const string& name) const {
428  return getInt(name);
429 }
430 template <>
431 double Policy::getValue<double>(const string& name) const {
432  return getDouble(name);
433 }
434 template <>
435 string Policy::getValue<string>(const string& name) const {
436  return getString(name);
437 }
438 template <>
439 Policy::FilePtr Policy::getValue<Policy::FilePtr>(const string& name) const {
440  return getFile(name);
441 }
442 template <>
443 Policy::ConstPtr Policy::getValue<Policy::ConstPtr>(const string& name) const {
444  return getPolicy(name);
445 }
446 
447 template <>
448 vector<bool> Policy::getValueArray<bool>(const string& name) const {
449  return getBoolArray(name);
450 }
451 template <>
452 vector<int> Policy::getValueArray<int>(const string& name) const {
453  return getIntArray(name);
454 }
455 template <>
456 vector<double> Policy::getValueArray<double>(const string& name) const {
457  return getDoubleArray(name);
458 }
459 template <>
460 vector<string> Policy::getValueArray<string>(const string& name) const {
461  return getStringArray(name);
462 }
463 template <>
464 Policy::FilePtrArray Policy::getValueArray<Policy::FilePtr>(const string& name) const {
465  return getFileArray(name);
466 }
467 template <>
468 Policy::PolicyPtrArray Policy::getValueArray<Policy::Ptr>(const string& name) const {
469  return getPolicyArray(name);
470 }
471 template <>
472 Policy::ConstPolicyPtrArray Policy::getValueArray<Policy::ConstPtr>(const string& name) const {
473  return getConstPolicyArray(name);
474 }
475 
476 template <>
477 Policy::ValueType Policy::getValueType<bool>() {
478  return BOOL;
479 }
480 template <>
481 Policy::ValueType Policy::getValueType<int>() {
482  return INT;
483 }
484 template <>
485 Policy::ValueType Policy::getValueType<double>() {
486  return DOUBLE;
487 }
488 template <>
489 Policy::ValueType Policy::getValueType<string>() {
490  return STRING;
491 }
492 template <>
493 Policy::ValueType Policy::getValueType<Policy>() {
494  return POLICY;
495 }
496 template <>
497 Policy::ValueType Policy::getValueType<Policy::FilePtr>() {
498  return FILE;
499 }
500 template <>
501 Policy::ValueType Policy::getValueType<Policy::Ptr>() {
502  return POLICY;
503 }
504 template <>
505 Policy::ValueType Policy::getValueType<Policy::ConstPtr>() {
506  return POLICY;
507 }
508 
509 template <>
510 void Policy::setValue(const string& name, const bool& value) {
511  set(name, value);
512 }
513 template <>
514 void Policy::setValue(const string& name, const int& value) {
515  set(name, value);
516 }
517 template <>
518 void Policy::setValue(const string& name, const double& value) {
519  set(name, value);
520 }
521 template <>
522 void Policy::setValue(const string& name, const string& value) {
523  set(name, value);
524 }
525 template <>
526 void Policy::setValue(const string& name, const Ptr& value) {
527  set(name, value);
528 }
529 template <>
530 void Policy::setValue(const string& name, const FilePtr& value) {
531  set(name, value);
532 }
533 
534 template <>
535 void Policy::addValue(const string& name, const bool& value) {
536  add(name, value);
537 }
538 template <>
539 void Policy::addValue(const string& name, const int& value) {
540  add(name, value);
541 }
542 template <>
543 void Policy::addValue(const string& name, const double& value) {
544  add(name, value);
545 }
546 template <>
547 void Policy::addValue(const string& name, const string& value) {
548  add(name, value);
549 }
550 template <>
551 void Policy::addValue(const string& name, const Ptr& value) {
552  add(name, value);
553 }
554 template <>
555 void Policy::addValue(const string& name, const FilePtr& value) {
556  add(name, value);
557 }
558 
561  vector<PropertySet::Ptr> psa = _getPropSetList(name);
563  for (i = psa.begin(); i != psa.end(); ++i) out.push_back(ConstPtr(new Policy(*i)));
564  return out;
565 }
566 
567 Policy::PolicyPtrArray Policy::getPolicyArray(const string& name) const {
568  PolicyPtrArray out;
569  vector<PropertySet::Ptr> psa = _getPropSetList(name);
571  for (i = psa.begin(); i != psa.end(); ++i) out.push_back(Ptr(new Policy(*i)));
572  return out;
573 }
574 
575 Policy::FilePtr Policy::getFile(const string& name) const {
576  FilePtr out = std::dynamic_pointer_cast<PolicyFile>(_data->getAsPersistablePtr(name));
577  if (!out.get()) throw LSST_EXCEPT(TypeError, name, string(typeName[FILE]));
578  return out;
579 }
580 
581 Policy::FilePtrArray Policy::getFileArray(const string& name) const {
582  FilePtrArray out;
583  vector<Persistable::Ptr> pfa = _getPersistList(name);
585  FilePtr fp;
586  for (i = pfa.begin(); i != pfa.end(); ++i) {
587  fp = std::dynamic_pointer_cast<PolicyFile>(*i);
588  if (!fp.get()) throw LSST_EXCEPT(TypeError, name, string(typeName[FILE]));
589  out.push_back(fp);
590  }
591 
592  return out;
593 }
594 
595 void Policy::set(const string& name, const FilePtr& value) {
596  _data->set(name, std::dynamic_pointer_cast<Persistable>(value));
597 }
598 
599 void Policy::add(const string& name, const FilePtr& value) {
600  _data->add(name, std::dynamic_pointer_cast<Persistable>(value));
601 }
602 
619 int Policy::loadPolicyFiles(const fs::path& repository, bool strict) {
620  fs::path repos = repository;
621  int result = 0;
622  if (repos.empty()) repos = ".";
623 
624  // iterate through the top-level names in this Policy
626  fileNames(names, true);
627  for (list<string>::iterator it = names.begin(); it != names.end(); it++) {
628  // iterate through the files in the value array
629  const FilePtrArray& pfiles = getFileArray(*it);
630  PolicyPtrArray pols;
631  pols.reserve(pfiles.size());
632 
633  FilePtrArray::const_iterator pfi;
634  for (pfi = pfiles.begin(); pfi != pfiles.end(); pfi++) {
635  // increment even if fail, since we will remove the file record
636  ++result;
637 
638  Ptr policy = std::make_shared<Policy>();
639  try {
640  fs::path path = (*pfi)->getPath();
641  // if possible, use the policy file's own loading mechanism
642  if (path.is_complete()) {
643  (*pfi)->load(*policy);
644  } else {
645  fs::path localPath = repos / (*pfi)->getPath();
646  PolicyFile(localPath.string()).load(*policy);
647  }
648  } catch (pexExcept::IoError& e) {
649  if (strict) {
650  throw e;
651  }
652  // TODO: log a problem
653  } catch (ParserError& e) {
654  if (strict) {
655  throw e;
656  }
657  // TODO: log a problem
658  }
659  // everything else will get sent up the stack
660 
661  pols.push_back(policy);
662  }
663 
664  remove(*it);
665  for (PolicyPtrArray::iterator pi = pols.begin(); pi != pols.end(); ++pi) add(*it, *pi);
666  }
667 
668  // Now iterate again to recurse into sub-Policy values
669  policyNames(names, true);
670  for (list<string>::iterator it = names.begin(); it != names.end(); it++) {
671  PolicyPtrArray policies = getPolicyArray(*it);
672 
673  // iterate through the Policies in this array
674  PolicyPtrArray::iterator pi;
675  for (pi = policies.begin(); pi != policies.end(); pi++)
676  result += (*pi)->loadPolicyFiles(repos, strict);
677  }
678 
679  return result;
680 }
681 
703 int Policy::mergeDefaults(const Policy& defaultPol, bool keepForValidation, ValidationError* errs) {
704  int added = 0;
705 
706  // if defaultPol is a dictionary, extract the default values
707  auto_ptr<Policy> pol(0);
708  const Policy* def = &defaultPol;
709  if (def->isDictionary()) {
710  // extract default values from dictionary
711  pol.reset(new Policy(false, Dictionary(*def)));
712  def = pol.get();
713  }
714 
715  list<string> params;
716  def->paramNames(params);
718  for (nm = params.begin(); nm != params.end(); ++nm) {
719  if (!exists(*nm)) {
720  const std::type_info& tp = def->getTypeInfo(*nm);
721  if (tp == typeid(bool)) {
722  BoolArray a = def->getBoolArray(*nm);
723  BoolArray::iterator vi;
724  for (vi = a.begin(); vi != a.end(); ++vi) add(*nm, *vi);
725  } else if (tp == typeid(int)) {
726  IntArray a = def->getIntArray(*nm);
727  IntArray::iterator vi;
728  for (vi = a.begin(); vi != a.end(); ++vi) add(*nm, *vi);
729  } else if (tp == typeid(double)) {
730  DoubleArray a = def->getDoubleArray(*nm);
731  DoubleArray::iterator vi;
732  for (vi = a.begin(); vi != a.end(); ++vi) add(*nm, *vi);
733  } else if (tp == typeid(string)) {
734  StringArray a = def->getStringArray(*nm);
735  StringArray::iterator vi;
736  for (vi = a.begin(); vi != a.end(); ++vi) add(*nm, *vi);
737  } else if (def->isFile(*nm)) {
738  FilePtrArray a = def->getFileArray(*nm);
739  FilePtrArray::iterator vi;
740  for (vi = a.begin(); vi != a.end(); ++vi) add(*nm, *vi);
741  } else {
742  // should not happen
744  string("Unknown type for \"") + *nm + "\": \"" + getTypeName(*nm) + "\"");
745  // added--;
746  }
747  added++;
748  }
749  }
750 
751  // if a dictionary is available, validate after all defaults are added
752  // propagate dictionary? If so, look for one and use it to validate
753  if (keepForValidation) {
754  if (defaultPol.isDictionary())
755  setDictionary(Dictionary(defaultPol));
756  else if (defaultPol.canValidate())
757  setDictionary(*defaultPol.getDictionary());
758  // if we couldn't find a dictionary, don't complain -- the API should
759  // work with default values even if defaultPol is a Policy without an
760  // attached Dictionary
761  if (canValidate()) getDictionary()->validate(*this, errs);
762  }
763  // don't keep a dictionary around, but validate anyway only if defaultPol is
764  // a Dictionary (if keepForValidation is false, there is a possibility that
765  // we don't want to use the attached Dictionary for validation)
766  else if (defaultPol.isDictionary())
767  Dictionary(defaultPol).validate(*this, errs);
768 
769  return added;
770 }
771 
772 /*
773  * return a string representation of the value given by a name. The
774  * string "<null>" is printed if the name does not exist.
775  */
776 string Policy::str(const string& name, const string& indent) const {
777  ostringstream out;
778 
779  try {
780  const std::type_info& tp = _data->typeOf(name);
781  if (tp == typeid(bool)) {
782  BoolArray b = getBoolArray(name);
783  BoolArray::iterator vi;
784  for (vi = b.begin(); vi != b.end(); ++vi) {
785  out << *vi;
786  if (vi + 1 != b.end()) out << ", ";
787  }
788  } else if (tp == typeid(int)) {
789  IntArray i = getIntArray(name);
790  IntArray::iterator vi;
791  for (vi = i.begin(); vi != i.end(); ++vi) {
792  out << *vi;
793  if (vi + 1 != i.end()) out << ", ";
794  }
795  } else if (tp == typeid(double)) {
796  DoubleArray d = getDoubleArray(name);
797  DoubleArray::iterator vi;
798  for (vi = d.begin(); vi != d.end(); ++vi) {
799  out << *vi;
800  if (vi + 1 != d.end()) out << ", ";
801  }
802  } else if (tp == typeid(string)) {
803  StringArray s = _data->getArray<string>(name);
804  StringArray::iterator vi;
805  for (vi = s.begin(); vi != s.end(); ++vi) {
806  out << '"' << *vi << '"';
807  if (vi + 1 != s.end()) out << ", ";
808  }
810  vector<PropertySet::Ptr> p = _data->getArray<PropertySet::Ptr>(name);
812  for (vi = p.begin(); vi != p.end(); ++vi) {
813  out << "{\n";
814  Policy(*vi).print(out, "", indent + " ");
815  out << indent << "}";
816  if (vi + 1 != p.end()) out << ", ";
817  out.flush();
818  }
820  FilePtrArray f = getFileArray(name);
821  FilePtrArray::iterator vi;
822  for (vi = f.begin(); vi != f.end(); ++vi) {
823  out << "FILE:" << (*vi)->getPath();
824  if (vi + 1 != f.end()) out << ", ";
825  out.flush();
826  }
827  } else {
828  throw LSST_EXCEPT(pexExcept::LogicError, "Policy: unexpected type held by any");
829  }
830  } catch (NameNotFound&) {
831  out << "<null>";
832  }
833 
834  // out << ends; // unnecessary but problematic, according to #316
835  return out.str();
836 }
837 
838 /*
839  * print the contents of this policy to an output stream
840  */
841 void Policy::print(ostream& out, const string& label, const string& indent) const {
842  list<string> nms;
843  names(nms, true);
844  if (label.size() > 0) out << indent << label << ":\n";
845  for (list<string>::iterator n = nms.begin(); n != nms.end(); ++n) {
846  out << indent << " " << *n << ": " << str(*n, indent + " ") << endl;
847  }
848 }
849 
850 /*
851  * convert the entire contents of this policy to a string. This
852  * is mainly intended for debugging purposes.
853  */
854 string Policy::toString() const {
856  print(os);
857  return os.str();
858 }
859 
860 //@endcond
861 
862 } // namespace policy
863 } // namespace pex
864 } // namespace lsst
static std::type_info const & typeOfT()
Get type info for the specified class.
std::vector< int > IntArray
Definition: Policy.h:176
std::shared_ptr< PolicyFile > FilePtr
Definition: Policy.h:173
std::shared_ptr< Policy > Ptr
Definition: Policy.h:169
definition of the PolicySource class
void set(const std::string &name, const Ptr &value)
Set a value with the given name.
Definition: Policy.h:972
std::vector< Ptr > PolicyPtrArray
Definition: Policy.h:179
static Policy * createPolicyFromUrn(const std::string &urn, bool validate=true)
Create a Policy from a file specified by a URN.
definition of the PolicyFile class
const ConstDictPtr getDictionary() const
The dictionary (if any) that this policy uses to validate itself, including checking set() and add() ...
Key< Flag > const & target
bool canValidate() const
Can this policy validate itself – that is, does it have a dictionary that it can use to validate its...
int policyNames(std::list< std::string > &names, bool topLevelOnly=false, bool append=false) const
load the names of parameters into a given list.
Definition: Policy.h:861
STL class.
table::Key< int > b
std::shared_ptr< const Dictionary > ConstDictPtr
Definition: Policy.h:172
T endl(T... args)
definition of Policy parsing exceptions
table::Key< int > a
STL namespace.
FilePtrArray getFileArray(const std::string &name) const
return an array of PolicyFile pointers associated with the given name.
void setDictionary(const Dictionary &dict)
Update this policy&#39;s dictionary that it uses to validate itself.
PolicyPtrArray getPolicyArray(const std::string &name) const
return an array of Policy pointers associated with the given name.
void validate(ValidationError *errs=0) const
Validate this policy, using its stored dictionary.
T end(T... args)
#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
static bool looksLikeUrn(const std::string &s, bool strict=false)
Does s look like a URN? That is, does it start with URN_PREFIX or URN_PREFIX_ABBREV?
static const char *const typeName[]
c-string forms for the supported value types.
Definition: Policy.h:193
bool isFile(const std::string &name) const
return true if the value pointed to by the given name is a PolicyFile
Definition: Policy.h:935
DoubleArray getDoubleArray(const std::string &name) const
return an array of values associated with the given name
Definition: Policy.h:968
STL class.
Reports errors in external input/output operations.
Definition: Runtime.h:160
FilePtr getFile(const std::string &name) const
return a PolicyFile (a reference to a file with "sub-Policy" data) identified by a given name...
STL class.
StringArray getStringArray(const std::string &name) const
return an array of values associated with the given name
Definition: Policy.h:960
bool getBool(const std::string &name) const
return a boolean value associated with the given name.
Definition: Policy.h:567
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
T push_back(T... args)
static FilePtr createPolicyFile(const std::string &pathOrUrn, bool strict=false)
Create a PolicyFile or UrnPolicyFile from pathOrUrn.
A base class for image defects.
bool exists(const std::string &name) const
return true if a value exists in this policy for the given name.
Definition: Policy.h:893
std::vector< std::string > StringArray
Definition: Policy.h:178
std::shared_ptr< RecordT > src
Definition: Match.cc:48
ConstPtr getPolicy(const std::string &name) const
return a "sub-Policy" identified by a given name.
Definition: Policy.h:953
T erase(T... args)
int getInt(const std::string &name) const
return an integer value associated with the given name.
Definition: Policy.h:579
int fileNames(std::list< std::string > &names, bool topLevelOnly=false, bool append=false) const
load the names of parameters into a given list.
Definition: Policy.h:864
void addValue(const std::string &name, const T &value)
Add a value to an array of values with a given name.
Definition: Policy.h:1152
T str(T... args)
const char * source()
Source function that allows astChannel to source from a Stream.
Definition: Stream.h:224
T dynamic_pointer_cast(T... args)
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
STL class.
const std::string getString(const std::string &name) const
return a string value associated with the given name .
Definition: Policy.h:603
void setValue(const std::string &name, const T &value)
Set a value with the given name.
Definition: Policy.h:1134
int mergeDefaults(const Policy &defaultPol, bool keepForValidation=true, ValidationError *errs=0)
use the values found in the given policy as default values for parameters not specified in this polic...
bool isPolicy(const std::string &name) const
return true if the value pointed to by the given name is a Policy
Definition: Policy.h:927
T count(T... args)
double getDouble(const std::string &name) const
return a double value associated with the given name.
Definition: Policy.h:591
T flush(T... args)
BoolArray getBoolArray(const std::string &name) const
return an array of values associated with the given name
Definition: Policy.h:964
T size(T... args)
Definition: __init__.py:1
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
std::vector< FilePtr > FilePtrArray
Definition: Policy.h:180
STL class.
T name(T... args)
STL class.
const char * getTypeName(const std::string &name) const
return a string name for the type associated with the parameter of a given name.
Definition: Policy.h:507
int names(std::list< std::string > &names, bool topLevelOnly=false, bool append=false) const
load the names of parameters into a given list.
Definition: Policy.h:855
std::vector< double > DoubleArray
Definition: Policy.h:177
T begin(T... args)
virtual void print(std::ostream &out, const std::string &label="Policy", const std::string &indent="") const
print the contents of this policy to an output stream.
Class for storing generic metadata.
Definition: PropertySet.h:67
Persistable(void)
Default constructor.
Definition: Persistable.cc:45
static ValueType getTypeByName(const std::string &name)
Given the human-readable name of a type ("bool", "int", "policy", etc), what is its ValueType (BOOL...
definition of the Dictionary class
static ValueType getValueType()
A template-ized way to get the ValueType.
Definition: Policy.h:1112
Base class for all persistable classes.
Definition: Persistable.h:75
virtual std::string str(const std::string &name, const std::string &indent="") const
return a string representation of the value given by a name.
table::Key< int > transform
int loadPolicyFiles(bool strict=true)
Recursively replace all PolicyFile values with the contents of the files they refer to...
Definition: Policy.h:747
std::vector< bool > BoolArray
Definition: Policy.h:175
std::ostream * os
Definition: Schema.cc:746
ConstPolicyPtrArray getConstPolicyArray(const std::string &name) const
return an array of Policy pointers associated with the given name.
STL class.
std::string toString() const
convert the entire contents of this policy to a string.
py::object result
Definition: _schema.cc:429
void add(const std::string &name, const Ptr &value)
Add a value to an array of values with a given name.
Definition: Policy.h:1007
std::shared_ptr< const Policy > ConstPtr
Definition: Policy.h:170
the definition of the UrnPolicyFile class
IntArray getIntArray(const std::string &name) const
return an array of values associated with the given name
Definition: Policy.h:966
Policy()
Create an empty policy.
std::vector< ConstPtr > ConstPolicyPtrArray
Definition: Policy.h:181
ValueType
an enumeration for the supported policy types
Definition: Policy.h:186
virtual ~Policy()
destroy this policy