lsst.pex.policy  18.1.0-1-g0001055+8
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) {
102  list<string> names;
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;
286  vector<string> src;
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;
334  vector<string> src;
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 
560  ConstPolicyPtrArray out;
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) {
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
625  list<string> names;
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 {
855  ostringstream os;
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()
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() ...
bool canValidate() const
Can this policy validate itself – that is, does it have a dictionary that it can use to validate its...
STL class.
virtual void load(Policy &policy) const
load the data from this Policy source into a Policy object.
std::shared_ptr< const Dictionary > ConstDictPtr
Definition: Policy.h:172
T endl(T... args)
definition of Policy parsing exceptions
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)
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
STL class.
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.
T push_back(T... args)
static FilePtr createPolicyFile(const std::string &pathOrUrn, bool strict=false)
Create a PolicyFile or UrnPolicyFile from pathOrUrn.
bool exists() const
return true if the file exists.
Definition: PolicyFile.h:171
PolicyFile(const std::string &filepath, const SupportedFormats::Ptr &fmts=defaultFormats)
create a Policy file that points a file with given path.
T erase(T... args)
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)
T dynamic_pointer_cast(T... args)
STL class.
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...
T count(T... args)
T flush(T... args)
T size(T... args)
#define LSST_EXCEPT(type,...)
std::vector< FilePtr > FilePtrArray
Definition: Policy.h:180
STL class.
T name(T... args)
STL class.
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.
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
std::shared_ptr< Persistable > Ptr
T transform(T... args)
virtual std::string str(const std::string &name, const std::string &indent="") const
return a string representation of the value given by a name.
int loadPolicyFiles(bool strict=true)
Recursively replace all PolicyFile values with the contents of the files they refer to...
Definition: Policy.h:747
PolicySource(SupportedFormats::Ptr fmts=defaultFormats)
create a Policy file that points a file with given path.
Definition: PolicySource.h:58
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.
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
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